Page 1 of 1
SOLVED : centering a dialog in an app
Posted: Sun Oct 15, 2023 3:06 pm
by Blue
A Windows question.
When an app displays a message in a dialog box, the OS Windows outputs the resulting dialog box in the centre of the screen.
But i'd really like to have that dialog box centered in my app, whatever its position.
Is there a PB or an API parameter or a method that will allow me to do that ?
Code: Select all
; A simple example
; Blue — October 15 2023
OpenWindow(0, 140, 140, 300, 300, "Some Windows app", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ButtonGadget(0, 20,20,120,24,"I have a request...")
Procedure Display_message()
Protected.s msg = "I'd like to be centered" + Chr(10) + "in my app..."
MessageRequester("Information", msg, 0)
EndProcedure
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow : Break
Case #PB_Event_Gadget : Display_message()
EndSelect
ForEver
End
Thanks in advance...
Re: How can I force Windows to center a dialog in my app ?
Posted: Sun Oct 15, 2023 4:14 pm
by firace
One way, using a callback (original code by netmaestro) - Use as a starting point
Code: Select all
Procedure MsgCallback(hWnd, Message, wParam, lParam)
Protected msgwin
Select message
Case #WM_WINDOWPOSCHANGING
msgwin=FindWindow_("#32770", "Confirmation required")
If msgwin
SetWindowPos_(msgwin,0,windowX(0)+40,windowY(0)+80,0,0,#SWP_NOSIZE|#SWP_NOZORDER)
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0, 100, 100, 540, 380, "")
SetWindowCallback(@MsgCallBack())
MessageRequester("Confirmation required", "Are you sure?", #PB_MessageRequester_YesNo)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: How can I force Windows to center a dialog in my app ?
Posted: Sun Oct 15, 2023 5:24 pm
by Blue
Thank you Firace.
That's certainly a very promising step in the right direction.
Using
NetMaestro's method, it becomes possible to position the dialog box very precisely.
If I may be so curious, how did you come across this code by
NetMaestro ? I spent over a good hour searching the forum, and i found nothing even approaching this. Could you provide a link to
NetMaestro's original code ?
The method he uses is what i was trying to implement; but try as I may, I just couldn't figure out the correct way to apply my calculated coordinates to the dialog box
BEFORE it was displayed by the system. It was quite frustrating...
So, again, a big thank you.
addendum : ————————————————————————————————
Using
MsgCallback as a search word, I found everything required, and more.
original code :
viewtopic.php?p=136950&hilit=MsgCallback#p136950
.
Re: SOLVED : centering a dialog in an app
Posted: Sun Oct 15, 2023 9:46 pm
by Blue
The annoying thing with the method suggested by NetMaestro is that all the dialog boxes in a given app have to use the exact same title to identify themselves. Otherwise, the Callback function won't find them and, therefore, won't be able to apply the repositioning hack.
Re: SOLVED : centering a dialog in an app
Posted: Sun Oct 15, 2023 10:14 pm
by AZJIO
Blue
I wrote the following code on AutoIt3, or rather there were two of them, one created a window in the visible area, the other centered it in the program and at the same time made it in the visible area, but apparently I did one code and not the second. When the dialog is centered, a problem arises if the window is partially moved off the screen, then the child window may appear off the screen and the user will not have access to it. You don’t see what is written there, it is possible to remove the disk from the OS, and the question is “Yes or No”, you press Enter expecting the worst consequences. You can't pull out the parent window because the child denies access to it until the child is closed, checkmate.
Try dragging the window off the screen and clicking the button
Code: Select all
EnableExplicit
Structure Rect2
x.l
y.l
w.l
h.l
EndStructure
;- Enumeration
Enumeration
#Win0
#Win_About
EndEnumeration
#w0_btn = 0
Global About$, ProgName$
Declare Win_About(ProgName$, Width = 270, Height = 170, WinID = -1)
ProgName$ = "ProgName"
About$ = "About"
;- GUI
OpenWindow(#Win0, 0, 0, 420, 300, "Win", #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
ButtonGadget(#w0_btn, 10, 10, 110, 30, About$)
;- Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case #w0_btn
Win_About(ProgName$, 300, 220, #Win0)
EndSelect
Case #PB_Event_CloseWindow
CloseWindow(#Win0)
End
EndSelect
ForEver
Procedure ChildCoor(*gp.Rect2, nWnd, w, h, c=0, d=0)
Protected DX, DY
*gp\w = WindowWidth(nWnd)
*gp\h = WindowHeight(nWnd)
*gp\x = WindowX(nWnd)
*gp\y = WindowY(nWnd)
ExamineDesktops()
DX=DesktopWidth(0)
DY=DesktopHeight(0)
If c = 0
*gp\x=*gp\x+(*gp\w-w)/2
*gp\y=*gp\y+(*gp\h-h)/2
EndIf
If *gp\x+w+d>DX
*gp\x=DX-w-10-d
EndIf
If *gp\y+h+60+d>DY
*gp\y=DY-h-70-d
EndIf
If *gp\x<=d
*gp\x=d
EndIf
If *gp\y<=d
*gp\y=d
EndIf
*gp\w=w
*gp\h=h
EndProcedure
Procedure Win_About(ProgName$, Width = 270, Height = 170, WinID = -1)
Protected hWnd
Protected gp.Rect2
If WinID > -1
hWnd = WindowID(WinID)
DisableWindow(WinID, #True)
Else
hWnd = 0
EndIf
ChildCoor(@gp, #Win0, Width, Height, 0, 30)
If OpenWindow(#Win_About, gp\x, gp\y, gp\w, gp\h, About$, #PB_Window_SystemMenu | #PB_Window_TitleBar, WindowID(#Win0))
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
If hWnd
DisableWindow(WinID, #False)
EndIf
CloseWindow(#Win_About)
ProcedureReturn 0
EndIf
EndProcedure
Re: SOLVED : centering a dialog in an app
Posted: Mon Oct 16, 2023 8:02 am
by firace
Blue wrote: Sun Oct 15, 2023 9:46 pm
The annoying thing with the method suggested by
NetMaestro is that all the dialog boxes in a given app have to use the exact same title to identify themselves. Otherwise, the Callback function won't find them and, therefore, won't be able to apply the repositioning hack.
Adapted to support multiple captions - hope this helps!
Code: Select all
Procedure MsgCallback(hWnd, Message, wParam, lParam)
Protected msgwin
Select message
Case #WM_WINDOWPOSCHANGING
captions.s = "Confirmation required::Prompt::Please confirm" ;; match all these captions - "::" is the separator
for a = 1 to CountString(captions, "::") + 1
msgwin=FindWindow_("#32770", StringField(captions, a, "::"))
if msgwin
break
endif
next
If msgwin
SetWindowPos_(msgwin,0,windowX(0)+40,windowY(0)+80,0,0,#SWP_NOSIZE|#SWP_NOZORDER)
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
OpenWindow(0, 100, 100, 540, 380, "")
SetWindowCallback(@MsgCallBack())
MessageRequester("Confirmation required", "Are you sure?", #PB_MessageRequester_YesNo)
MessageRequester("Please confirm", "Are you sure?", #PB_MessageRequester_YesNo)
MessageRequester("Not this one", "Are you sure?", #PB_MessageRequester_YesNo)
MessageRequester("Prompt", "Are you sure?", #PB_MessageRequester_YesNo)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Re: SOLVED : centering a dialog in an app
Posted: Mon Oct 16, 2023 8:59 am
by Shardik
Thread
MessageRequester centered with your main window from Juli 2009 with examples from flaith and netmaestro.
Re: SOLVED : centering a dialog in an app
Posted: Mon Oct 16, 2023 3:13 pm
by Blue
You've been hard at work,
firace...
firace wrote: Mon Oct 16, 2023 8:02 am
[...]
Adapted to support multiple captions - hope this helps!
Code: Select all
[...]
Procedure MsgCallback(hWnd, Message, wParam, lParam)
{etc}
EndProcedure
[...]
Great minds definitely think alike !
I did
exactly what you're suggesting here.
And, as you've already been able to verify, it works nicely.
Thanks
firace
Re: SOLVED : centering a dialog in an app
Posted: Mon Oct 16, 2023 6:53 pm
by Sicro
This is how I did it in an old program of mine.
If the window
#Window_Main was moved partially out of the screen, it does not work. Then the message requester is in the middle of the screen again.
Code: Select all
Enumeration Window
#Window_Main
EndEnumeration
Enumeration Gadget
#Button_Show_MsgBox
EndEnumeration
Global.RECT screenRect
Global resetWorkAreaTimer
Procedure ResetWorkArea(hWnd, uMsg, wParam, lParam)
; Reset the work area size
SystemParametersInfo_(#SPI_SETWORKAREA, 0, @screenRect, 0)
KillTimer_(0, resetWorkAreaTimer)
EndProcedure
Procedure ShowMsgBox()
Protected.RECT windowRect
Protected result = #False
; Reduce work area to the size of #Window_Main
If SystemParametersInfo_(#SPI_GETWORKAREA, 0, @screenRect, 0) And
GetWindowRect_(WindowID(#Window_Main), @windowRect)
result = SystemParametersInfo_(#SPI_SETWORKAREA, 0, @windowRect, 0)
EndIf
If result
resetWorkAreaTimer = SetTimer_(0, 0, 1, @ResetWorkArea())
EndIf
MessageRequester("Example", "This is a centered message box.")
EndProcedure
OpenWindow(#Window_Main, 300, 300, 800, 800, "Test", #PB_Window_SystemMenu)
ButtonGadget(#Button_Show_MsgBox, 800/2 - 100/2, 800/2 - 20/2, 100, 20, "Show MsgBox")
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
ShowMsgBox()
EndIf
Until event = #PB_Event_CloseWindow
Re: SOLVED : centering a dialog in an app
Posted: Mon Oct 16, 2023 7:14 pm
by AZJIO
I'd like to illustrate my thesis with an example.
Code: Select all
Global DsktpWidth
ExamineDesktops()
DsktpWidth = DesktopWidth(0)
Procedure MsgCallback(hWnd, Message, wParam, lParam)
Protected msgwin
Select message
Case #WM_WINDOWPOSCHANGING
captions.s = "Format the hard drive" ;; match all these captions - "::" is the separator
For a = 1 To CountString(captions, "::") + 1
msgwin=FindWindow_("#32770", StringField(captions, a, "::"))
If msgwin
Break
EndIf
Next
If msgwin
SetWindowPos_(msgwin,0,WindowX(0)+40,WindowY(0)+80,0,0,#SWP_NOSIZE|#SWP_NOZORDER)
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
; While the backup was in progress, we moved the window to the side
OpenWindow(0, DsktpWidth - 40, 100, 540, 380, "Press Enter/Esc if you don’t know what to do, maybe you’ll get lucky")
SetWindowCallback(@MsgCallBack())
If MessageRequester("Format the hard drive", "Unable to create a data backup. Format a hard disk without a backup?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
Debug "Thank you for agreeing to format your hard drive."
EndIf
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow