Hello,
Does anyone know how Windows and PB handle hyphenation of strings in message boxes?
I've been wondering about this for a long time, but I've never found any precise information.
I've noticed that, whereas some applications can display strings of varying character lengths on a single line, PB does it on several lines. These applications didn't give me the impression of using anything other than the classic Windows dialog boxes (but maybe I'm wrong...).
Under PB, I tried with strings without spaces or with non-breaking spaces, but they were inevitably cut "very" short without any particular logic (except perhaps the length in pixels?), even when there were non-breaking spaces.
Thank you for giving me more light on the subject..,
Hyphenation in Windows/PB MessageRequesters
Hyphenation in Windows/PB MessageRequesters
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
Except on this sentence...
Re: Hyphenation in Windows/PB MessageRequesters
HI boddhi,
sorry that I cannot answer your question. Instead I did some research on the topic.
Here you can see the results.
It looks like the size of the messagebox (messagerequester) and the controls (gadgets) are responsible.
sorry that I cannot answer your question. Instead I did some research on the topic.
Here you can see the results.
It looks like the size of the messagebox (messagerequester) and the controls (gadgets) are responsible.
Code: Select all
;/===
;| Some experimental code by Axolotl
;| (w/o having followed my coding guidelines)
;|
;| Update: Compare MessageRequester vs. Messagebox_
;\---
EnableExplicit
#Caption$ = "Very Long Text"
Global LongText$
Global AdditionalWidth = 0 ; add to message box width (see what happend)
; ---------------------------------------------------------------------------------------------------------------------
Procedure InitLongText()
Protected index, jj
LongText$ = ""
For index = 1 To 10
LongText$ + "/" + index + "/ "
For jj = 1 To 10
LongText$ + "This_is_a_very_long_text. " ; _ will be replaced with NBSP (non-break space)
Next jj
LongText$ + #LF$
Next index
LongText$ + #LF$ + "/3/ End of Text. "
ReplaceString(LongText$, "_", Chr(160)) ; mix the SPaces up with NBSP
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Macro HandleToStr(handle)
"0x" + Hex(handle, #PB_Quad) + " (" + Str(handle) + ")"
EndMacro
; ---------------------------------------------------------------------------------------------------------------------
Macro Trace(Message)
AddGadgetItem (10, -1, Message)
SetGadgetState(10, CountGadgetItems(10)-1)
EndMacro
; ---------------------------------------------------------------------------------------------------------------------
Procedure.s GetClassName(hWnd) ; returns the Classname of the specified window
Protected className.s{#MAX_PATH}
GetClassName_(hWnd, @className, #MAX_PATH)
ProcedureReturn className
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure HookCB(nCode, wParam, lParam)
Protected *cw.CBT_CREATEWND, *cs.CREATESTRUCT
Protected class$
Protected hStatic
Select nCode
Case #HCBT_ACTIVATE
Trace("#HCBT_ACTIVATE == " + HandleToStr(wParam))
class$ = GetClassName(wParam)
Trace(" Class = " + class$)
Select class$
Case "#32770" ; the MessageRequester
; be careful ....
; the next line will change all Buttons with #IDOK
;
SetDlgItemText_(wParam, #IDOK, @"Test") ; change the button text
EndSelect
Case #HCBT_CREATEWND ; .. wParam is the handle of the new window
Trace("#HCBT_CREATEWND == " + HandleToStr(wParam))
class$ = GetClassName(wParam)
Trace(" Class = " + class$)
*cw = lParam ;
; Debug "hwndinsertAfter = " + HandleToStr(*cw\hWndInsertAfter)
*cs = *cw\lpcs ; member struct
If *cs\hWndParent
Trace(" Child of or Ownded by " + HandleToStr(*cs\hWndParent))
EndIf
Trace(" Style = 0x" + Hex(*cs\style, #PB_Long) + ", 0x" + Hex(*cs\dwExStyle, #PB_Long))
Trace(" Size = " + Str(*cs\cx) + ", " + Str(*cs\cy))
Select class$
Case "#32770" ; the MessageRequester
*cs\cx + AdditionalWidth
; *cs\cy + 100
Case "Static" ;
*cs\cx + AdditionalWidth
; *cs\cy + 100
Case "Button" ; Button, ...
*cs\x + AdditionalWidth
; *cs\y + 100
; Case ""
Default ; IME, CicMarshallWndClass, MSCTFIME UI, SystemUserAdapterWindowClass .... ???
EndSelect
Case #HCBT_DESTROYWND
Trace("#HCBT_DESTROYWND == " + HandleToStr(wParam))
EndSelect
ProcedureReturn #False
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure DisplayText(Which, bShowIcon)
Protected result, hHook, flags_pb, flags_mb
; start hooking :;
hHook = SetWindowsHookEx_(#WH_CBT, @HookCB(), 0, GetCurrentThreadId_())
If bShowIcon ; add the correct value
flags_pb = #PB_MessageRequester_Info
flags_mb = #MB_ICONINFORMATION
EndIf
Select Which
Case 1 ; Purebaisc Original
Trace("MessageRequester ----------------------------------------")
result = MessageRequester(#Caption$, LongText$, flags_pb | #PB_MessageRequester_Ok)
Case 2 ; M$
Trace("MessageBox_ ---------------------------------------------")
result = MessageBox_(0, @LongText$, #Caption$, flags_mb | #MB_SYSTEMMODAL | #MB_OK)
Default
result = -1
EndSelect
Trace("Return " + result)
Trace("")
; stop hooking
UnhookWindowsHookEx_(hHook)
ProcedureReturn result
EndProcedure
; ---------------------------------------------------------------------------------------------------------------------
Procedure main()
Protected dlgWhich, showIcon
InitLongText()
If OpenWindow(0, 0, 0, 600, 400, "Inspect MessageRequester() vs. Messagebox_() ... ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StickyWindow(0, 1) ; I want my app on top of all others (especially the IDE)
; button line
ButtonGadget( 0, 10, 0, 120, 23, "Show Message")
OptionGadget(11, 140, 0, 90, 20, "Width + 0")
OptionGadget(12, 140, 25, 90, 20, "Width + 200")
OptionGadget(13, 140, 50, 90, 20, "Width + 400")
TextGadget( 1, 0, 0, 0, 0, "") : HideGadget(1, 1) ; create a new Options Group ???
OptionGadget(21, 240, 0, 80, 20, "PureBasic")
OptionGadget(22, 240, 25, 80, 20, "MicroSoft")
CheckBoxGadget(2, 340, 0, 80, 23, "Show Icon")
; output some info
;
ListViewGadget(10, 10, 80, 580, 310, $4000) ; we are on windows, so we can use the special flag #LBS_NOSEL
SetGadgetFont(10, LoadFont(0, "consolas", 9))
; init
SetGadgetState(11, 1) : AdditionalWidth = 0
SetGadgetState(21, 1) : dlgWhich = 1
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow : Break ; bye
Case #PB_Event_Gadget
Select EventGadget()
Case 0 : DisplayText(dlgWhich, ShowIcon) ; Show Message
Case 11 : AdditionalWidth = 0
Case 12 : AdditionalWidth = 200
Case 13 : AdditionalWidth + 400
Case 21 : dlgWhich = 1
Case 22 : dlgWhich = 2
Case 2 : showIcon ! 1 ; CheckBox toggle
EndSelect
EndSelect
ForEver
EndIf
ProcedureReturn 0
EndProcedure
End main()
Last edited by Axolotl on Tue Jul 02, 2024 3:40 pm, edited 1 time in total.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Re: Hyphenation in Windows/PB MessageRequesters
Hello Axolotl,
To tell the truth, I haven't fully studied it yet because, as a Sunday programmer, I'm not yet familiar with the APIs you've used. I'll get to work
About the native MessageRequester() function, PB seems to contain the text within a regular limit. I can't fully confirm this as I only have 1920p screens, but every time, the width of the dialog boxes never exceeds 30% of the screen width (icon or not).
Thanks a lot for your code.Axolotl wrote: [...] Here you can see the results. [...]
To tell the truth, I haven't fully studied it yet because, as a Sunday programmer, I'm not yet familiar with the APIs you've used. I'll get to work

About the native MessageRequester() function, PB seems to contain the text within a regular limit. I can't fully confirm this as I only have 1920p screens, but every time, the width of the dialog boxes never exceeds 30% of the screen width (icon or not).
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
Except on this sentence...
Re: Hyphenation in Windows/PB MessageRequesters
Hi boddhi,
It's not a problem if you're not familiar with the API stuff.
The hook is only for inspection of the message windows.
With this update (see my first post) you can see that there is no difference between PB and original windows.
Because the hook can also influence the creation process of the window, I have changed the width of the Requester/MessageBox.
You can see that the calculation of the size is already completed, but the text is adapted to the new width.
A distinction is made between SPACE (chr(32)) and NBSP. (chr(160))
If you want play with it, the procedrue InitLongText() creates the text now.
It's not a problem if you're not familiar with the API stuff.
The hook is only for inspection of the message windows.
With this update (see my first post) you can see that there is no difference between PB and original windows.
Because the hook can also influence the creation process of the window, I have changed the width of the Requester/MessageBox.
You can see that the calculation of the size is already completed, but the text is adapted to the new width.
A distinction is made between SPACE (chr(32)) and NBSP. (chr(160))
If you want play with it, the procedrue InitLongText() creates the text now.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).