Msgbox always shown in CENTER of parent GUI window

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Msgbox always shown in CENTER of parent GUI window

25 Oct 2023, 16:45

Hello,
Msgbox always is shown in CENTER of the SCREEN.

But, is there a way to "force" msgbox always shown in CENTER of parent GUI window (parent GUI window = the GUI window which call that msgbox) , please?
Rohwedder
Posts: 7774
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Msgbox always shown in CENTER of parent GUI window

26 Oct 2023, 02:22

Hallo,
use a Timer to move the MsgBox or use MsgBox() with the center coordinates of parent GUI:

Code: Select all

q::MsgBox("Hello", "moved MsgBox",, 100, 200)

MsgBox(Params*) ; (Text, Title, Options, X, Y)
{ ;based on: jeeswg AHK v2 functions for AHK v1
    local Match, Options, Result, Temp, Text, Timeout, Title, Type
    static TypeArray := {"OK":0, "O":0, "OKCancel":1, "O/C":1, "OC":1, "AbortRetryIgnore":2, "A/R/I":2, "ARI":2
        , "YesNoCancel":3, "Y/N/C":3, "YNC":3, "YesNo":4, "Y/N":4, "YN":4, "RetryCancel":5, "R/C":5, "RC":5
        , "CancelTryAgainContinue":6, "C/T/C":6, "CTC":6, "Iconx":16, "Icon?":32, "Icon!":48, "Iconi":64
        , "Default2":256, "Default3":512, "Default4":768}
    Text := !Params.Length() ? "Press OK to continue." : Params.HasKey(1) ? Params.1 : ""
    Title := !Params.HasKey(2) ? A_ScriptName : (Params.2 = "") ? " " : Params.2
    Options := Params.3, Timeout := "", Type := 0
    if (Options)
    {
        Loop, Parse, Options, % " `t"
            (Temp := Abs(A_LoopField)) || (Temp := TypeArray[A_LoopField]) ? (Type |= Temp)
                : RegExMatch(A_LoopField, "Oi)^T(\d+\.?\d*)$", Match) ? Timeout := Match.1
                : 0
    }
    SetTimer, MoveMsgBox,% (Params.HasKey(4) And Params.HasKey(5))?-1:"Off"
    MsgBox % Type, % Title, % Text, % Timeout
    Loop Parse, % "Timeout,OK,Cancel,Yes,No,Abort,Ignore,Retry,Continue,TryAgain", % ","
        IfMsgBox % Result := A_LoopField
            break
    Return Result
    MoveMsgBox:
    WinHide,% MsgBox := Title " ahk_class #32770 ahk_pid " DllCall("GetCurrentProcessId")
    DetectHiddenWindows, On
    WinMove,% MsgBox,,% Params.4,% Params.5
    WinShow,% MsgBox
    Return
}
Edit: DllCall("GetCurrentProcessId") makes the WinMove target safer.
Last edited by Rohwedder on 27 Oct 2023, 01:22, edited 1 time in total.
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

26 Oct 2023, 14:37

Thank you very much.
Please let me further ask:

(1)
How can we use MsgBox() with the center coordinates of parent GUI ?

(2)
Is there any more simple solution?
Like something the following : ???

Code: Select all

Gui +Owndialogs +GUIcenter
msgbox, Hello
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: Msgbox always shown in CENTER of parent GUI window

26 Oct 2023, 15:53

GEOVAN wrote:
26 Oct 2023, 14:37
Thank you very much.
Please let me further ask:

(1)
How can we use MsgBox() with the center coordinates of parent GUI ?

(2)
Is there any more simple solution?
Like something the following : ???

Code: Select all

Gui +Owndialogs +GUIcenter
msgbox, Hello
His code can be simplified a bit.

This has centering added.

Code: Select all

#SingleInstance Force
SetBatchLines, -1
;=====================Main Window=====================
Gui, New, +AlwaysOnTop +hwndGuiHwnd
Gui, Margin, 100 , 100
Gui, Add, Button, w200 h50 gShowMessage , Show Message
Gui, Show,, Main Window
;=====================================================

return
*ESC::ExitApp

ShowMessage:
	
	Gui, % GuiHwnd ": +OwnDialogs"				
	
	;set a timer to move the msgbox
	SetTimer, MoveMsgBox , -1
	
	;Your msgbox
	MsgTitle := "Demo Message"   ; *required*
	MsgText := "This is the contents of my message`nThe more contents I have in the msgbox`nthe better the chance of the msgbox being hidden`nbefore being moved"
	MsgBox,, % MsgTitle , % MsgText 
	
	;actions after the msgbox is closed
	SoundBeep 
	
	return

;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MoveMsgBox:
	
	;hide the window (works for msgbox with lots of text. i.e. hides and moves it before you see it)
	WinHide, % title := MsgTitle " ahk_class #32770"
	
	;turn on hidden window detection.
	DetectHiddenWindows, On
	
	;Get the width and height of the msgbox
	WinGetPos, mX , mY , mW , mH , % title 
	
	;Get the position of your main window
	WinGetPos, wX , wY , wW , wH , % "ahk_ID " GuiHwnd
	
	;calculate the center of your window
	x := wx + ( ( wW - mW ) / 2 )
	y := wy + ( ( wH - mH ) / 2 )
	
	;move the msgbox
	WinMove, % title , ,  % x , % y
	
	;show the msgbox
	WinShow, % title
	return
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||	
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: Msgbox always shown in CENTER of parent GUI window

27 Oct 2023, 15:19

You can also just create your own custom msgbox and have full control of *everything.

.
custom msgbox 1.gif
custom msgbox 1.gif (817.94 KiB) Viewed 1717 times
.

Example Function
Adding more buttons is easy.

Code: Select all

;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;text 			:= 	"Blah blah blah"									;The text to display
;title 			:= 	"Demo Msgbox 2"										;The title for the msgbox
;glabel 		:= 	"DemoOkButton"										;The label to call when the "OK" button is pressed
;options 		:= 	" +Owner" GuiHwnd									;The options for the msgbox window. eg. "+AlwaysOnTop +Owner -Caption etc..."
;rectObj 		:= 	{ X: "Center" , Y: "Center" , W: 150 , H: 500 }		;The size / position to use for the msgbox window. Use "Center" for both the x and y values to have the msgbox center on the parent PosObj you supply (x and y values are optional). W and H values are optional but both are needed to be used at all.
;textOptions 	:= 	" Center 0x200 +Border"								;The options for the text [0x200 = vertical center]
;wait 			:= 	1													;Wait for the msgbox to be closed before proceeding
;posObj 		:= 	{ X: x , Y: y , W: w , H: h }						;The position of the main window (target window). Used for positioning the msgbox relative to the owner. 
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;Custom Msgbox Function.
customMsgbox( text , title := "" , glabel := "" , options := "+Owner +LastFound" , rectObj := "" , textOptions := " Center 0x200 " , wait := 1 , posObj := "" ){
	static ButtonArea := { MinWidth: 100 , H: 40 } , buttonWidth := 75 , buttonHeight := 22 
	, fontSize := 8 , FontType := "Segoe UI" , FontColor := "000000"
	, BackgroundColor1 := "F0F0F0" , BackgroundColor2 := "FFFFFF"
	Gui, New, % " +HwndGuiHwnd -MinimizeBox -SysMenu " options , % title
	Gui, Margin, 0 , 0
	Gui, Color, % BackgroundColor1
	Gui, Font, s%fontSize% c%FontColor% , % FontType
	if( rectObj.Haskey( "W" ) && rectObj.Haskey( "H" ) ){
		Gui, Add, Progress, % "x0 y0 w" rectObj.W " h" rectObj.H - ButtonArea.H " Background" BackgroundColor2
		Gui, Add, Text, % "x10 y10 w" rectObj.W - 20 " h" rectObj.H - ButtonArea.H - 20 " BackgroundTrans " textOptions , % Text
		DetectHiddenWindows, On
		Gui, Show, Hide AutoSize
		WinGetPos,,, w, h , % "ahk_id " GuiHwnd
		if( glabel )
			Gui, Add, Button, % "x" w - buttonWidth - 20 " y" rectObj.H - ButtonArea.H + 10 " w" buttonWidth " h" buttonHeight " Default g" glabel , Ok
		else
			Gui, Add, Button, % "x" w - buttonWidth - 20 " y" rectObj.H - ButtonArea.H + 10 " w" buttonWidth " h" buttonHeight " gCMB1 Default" , Ok
	}else{
		Gui, Dummy:Font, s%fontSize% cBlack , % FontType
		Gui, Dummy:Add, Text, , % text
		GuiControlGet, pos, Dummy:pos , static1
		Gui, Dummy:Destroy
		Gui, % GuiHwnd ":Add", Progress, % "x0 y0 w" ( ( posW < 180 ) ? ( 180 + 20 ) : ( posW + 20 ) ) " h" ( ( posH < 40 ) ? ( 40 + 20 ) : ( posH + 20 ) ) " Background" BackgroundColor2 
		Gui, % GuiHwnd ":Add", Text, % "x10 y10 w" ( ( posW < 180 ) ? ( 180 ) : ( posW ) ) " h" ( ( posH < 40 ) ? ( 40 ) : ( posH ) ) " BackgroundTrans " textOptions , % Text
		DetectHiddenWindows, On
		Gui, % GuiHwnd ":Show", Hide AutoSize
		WinGetPos,,, w, h , % "ahk_id " GuiHwnd
		if( glabel )
			Gui, % GuiHwnd ":Add", Button, % "x" w - buttonWidth - 20 " y" ( ( posH < 40 ) ? ( 40 + 20 + 10 ) : ( posH + 20 + 10 ) ) " w" buttonWidth " h" buttonHeight " Default g" glabel , Ok
		else
			Gui, % GuiHwnd ":Add", Button, % "x" w - buttonWidth - 20 " y" ( ( posH < 40 ) ? ( 40 + 20 + 10 ) : ( posH + 20 + 10 ) ) " w" buttonWidth " h" buttonHeight " gCMB1 Default" , Ok
	}
	Gui, % GuiHwnd ":Margin", 0 , 10
	if( rectObj.Haskey( "X" ) && rectObj.Haskey( "Y" ) ){
		if( rectObj.X = "Center" && rectObj.Y = "Center" && isObject( posObj ) ){
			WinGetPos,,, w , h , % "ahk_id " GuiHwnd
			x := posObj.X + ( posObj.W - w ) / 2
			y := posObj.Y + ( posObj.H - h ) / 2
			Gui, % GuiHwnd ":Show", % " AutoSize x" X " y" Y 
		}else{
			Gui, % GuiHwnd ":Show", % " AutoSize x" rectObj.X " y" rectObj.Y , % title
		}
	}else
		Gui, % GuiHwnd ":Show", AutoSize
	if( wait )
		WinWaitClose, % "ahk_id " GuiHwnd
	return
	CMB1:
		Gui, % A_Gui ":Destroy"
		return	
}
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|

Example Use

Code: Select all

#Include customMsgbox.ahk
#SingleInstance Force
;=====================================================
sampleText = 
( 
F2 -> Removes the Menu bar of the GUI

F3 -> Bring back the Menu bar of the GUI

F4 -> Makes the GUI window not resizable

F5 -> Makes the GUI window resizable
)
;=====================Main Window=====================
Gui, New, +AlwaysOnTop +hwndGuiHwnd
Gui, Color, acacac
Gui, Margin, 100 , 150
Gui, Add, Button, w200 h50 gShowMessage1 , Show Message 1
Gui, Margin, 100 , 10
Gui, Add, Button, w200 h50 gShowMessage2 , Show Message 2
Gui, Add, Button, w200 h50 gShowMessage3 , Show Message 3
Gui, Margin, 100 , 100
Gui, Show,, Main Window
;=====================================================
return

*ESC::ExitApp
;=====================================================Message 1
ShowMessage1:	;{

	;Disable your main window
	Gui, % GuiHwnd ":+Disabled"				
	
	;Get the position of your main window
	WinGetPos, x , y , w , h , % "ahk_ID " GuiHwnd
	
	;create a new msgbox
	customMsgbox( sampleText , "Demo Message 1" ,, " +Owner" GuiHwnd , { X: "Center" , Y: "Center" } , "" , 1 , { X: x , Y: y , W: w , H: h } )
	
	;enable your main window
	Gui, % GuiHwnd ":-Disabled"
	
	return
;}
;=====================================================Message 2
ShowMessage2:	;{
	Gui, % GuiHwnd ":+Disabled"
	WinGetPos, x , y , w , h , % "ahk_ID " GuiHwnd
	;===================================================
	text 			:= 	"Blah blah blah"									;The text to display
	title 			:= 	"Demo Msgbox 2"										;The title for the msgbox
	label 			:= 	"DemoOkButton"										;The label to call when the "OK" button is pressed
	options 		:= 	" +Owner" GuiHwnd									;The options for the msgbox window. eg. "+AlwaysOnTop +Owner -Caption etc..."
	rectObject 		:= 	{ X: "Center" , Y: "Center" , W: 150 , H: 500 }		;The size / position to use for the msgbox window
	textOptions 	:= 	" Center 0x200 +Border"								;The options for the text [0x200 = vertical center]
	wait 			:= 	1													;Wait for the msgbox to be closed before proceeding
	parentRect 		:= 	{ X: x , Y: y , W: w , H: h }						;The position of the main window (target window). Used for positioning the msgbox relative to the owner. 
	;===================================================
	customMsgbox( text , title , label , options , rectObject , textOptions , wait , parentRect )
	Gui, % GuiHwnd ":-Disabled"
	return
;}
;=====================================================Message 3
ShowMessage3:	;{
	;===================================================
	text 			:= 	"Child Window Msgbox`nSits inside the parent window"
	options 		:= 	"+Border -Caption +Parent" GuiHwnd
	rectObject 		:= 	{ X: 10 , Y: 10 }
	textOptions 	:= 	" Center  +Border "
	wait 			:=  1
	;===================================================
	customMsgbox( text ,,, options , rectObject , textOptions , wait )
	return
;}
;=====================================================Demo Ok Button Label
DemoOkButton:	;{
	Gui, % A_Gui ":Destroy"
	return
;}

GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

28 Oct 2023, 00:27

Thank you very very much!!!!!
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

29 Oct 2023, 00:48

Thank you very very much!!!
I like very much the last idea - to create your own custom msgbox and have full control of *everything.
I try to add (an additional button that is OK button and CANCEL button) which in normal msgbox it is given by:

Code: Select all

MsgBox 0x1, , 
But i can not figure how can i add it in your last demonstration. Can you please show how can we add more buttons like for example -

Code: Select all

MsgBox 0x1, , 
image.png
image.png (1.21 KiB) Viewed 1645 times
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: Msgbox always shown in CENTER of parent GUI window

29 Oct 2023, 18:51

GEOVAN wrote:
29 Oct 2023, 00:48
Thank you very very much!!!
I like very much the last idea - to create your own custom msgbox and have full control of *everything.
I try to add (an additional button that is OK button and CANCEL button) which in normal msgbox it is given by:

Code: Select all

MsgBox 0x1, ,
But i can not figure how can i add it in your last demonstration. Can you please show how can we add more buttons like for example -

Code: Select all

MsgBox 0x1, ,
image.png

Here is the original code with a new button added.

.
custom msgbox 2 buttons.gif
custom msgbox 2 buttons.gif (597.13 KiB) Viewed 1574 times
.

Your "PLAN A" should be to try to understand how it works and then create your own custom msgbox.
"Plan B" should be to try to understand my code enough to use it.

Change details.

I added a new argument for the customMsgbox function. UseCancelButton ( 0 = don't use , 1 = use )

I also changed the "ButtonArea.MinWidth" so that the new button will always fit. ( static var in the function )

I added a bit of logic and added in the new button control

Code: Select all

	if( glabel ){
			if( UseCancelButton ){
	;...
	;...
To use the new button you need to set UseCancelButton to 1 and attach a label to be called when you press on any of the buttons.

See the Message 3 example and the label DemoOkButton: to see an example of how to use the buttons.

Code: Select all

#SingleInstance Force
;=====================================================
sampleText = 
( 
F2 -> Removes the Menu bar of the GUI

F3 -> Bring back the Menu bar of the GUI

F4 -> Makes the GUI window not resizable

F5 -> Makes the GUI window resizable
)
;=====================Main Window=====================
Gui, New, +AlwaysOnTop +hwndGuiHwnd
Gui, Color, cdcdcd
Gui, Margin, 100 , 100
Gui, Add, Button, w200 h50 gShowMessage1 , Show Message 1
Gui, Margin, 100 , 10
Gui, Add, Button, w200 h50 gShowMessage2 , Show Message 2
Gui, Add, Button, w200 h50 gShowMessage3 , Show Message 3
Gui, Margin, 100 , 100
Gui, Show,, Main Window
;=====================================================
return

*ESC::ExitApp
;=====================================================Message 1
ShowMessage1:	;{

	;Disable your main window
	Gui, % GuiHwnd ":+Disabled"				
	
	;Get the position of your main window
	WinGetPos, x , y , w , h , % "ahk_ID " GuiHwnd
	
	;create a new msgbox
	customMsgbox( sampleText , "Demo Message 1" ,, " +Owner" GuiHwnd , { X: "Center" , Y: "Center" } , "" , 1 , { X: x , Y: y , W: w , H: h } )
	
	;enable your main window
	Gui, % GuiHwnd ":-Disabled"
	
	return
;}
;=====================================================Message 2
ShowMessage2:	;{
	Gui, % GuiHwnd ":+Disabled"
	WinGetPos, x , y , w , h , % "ahk_ID " GuiHwnd
	;===================================================
	text 			:= 	"Blah blah blah"									;The text to display
	title 			:= 	"Demo Msgbox 2"										;The title for the msgbox
	label 			:= 	"DemoOkButton"										;The label to call when the "OK" button is pressed
	options 		:= 	" +Owner" GuiHwnd									;The options for the msgbox window. eg. "+AlwaysOnTop +Owner -Caption etc..."
	rectObject 		:= 	{ X: "Center" , Y: "Center" , W: 150 , H: 500 }		;The size / position to use for the msgbox window
	textOptions 	:= 	" Center 0x200 +Border"									;The options for the text [0x200 = vertical center]
	wait 			:= 	1													;Wait for the msgbox to be closed before proceeding
	parentRect 		:= 	{ X: x , Y: y , W: w , H: h }						;The position of the main window (target window). Used for positioning the msgbox relative to the owner. 
	UseCancelButton	:= 	1
	;===================================================
	customMsgbox( text , title , label , options , rectObject , textOptions , wait , parentRect , UseCancelButton )
	Gui, % GuiHwnd ":-Disabled"
	return
;}
;=====================================================Message 3
ShowMessage3:	;{
	;===================================================
	text 			:= 	"Child Window Msgbox"
	Label			:=  "DemoOkButton"
	options 		:= 	"+Border -Caption +Parent" GuiHwnd
	rectObject 		:= 	{ X: 10 , Y: 10 , W: 250 , H: 80 }
	textOptions 	:= 	" Center 0x200 +Border "
	wait 			:=  1
	UseCancelButton	:= 	1
	;===================================================
	customMsgbox( text ,, Label , options , rectObject , textOptions , wait ,, UseCancelButton )
	if( MsgButtonPressed = "Ok" ){
		SoundBeep, 999
	}else if( MsgButtonPressed = "Cancel" ){
		SoundBeep, 999
		SoundBeep, 777
		SoundBeep, 555
	}
	MsgButtonPressed := ""
	return
;}
;=====================================================Demo Ok Button Label
DemoOkButton:	;{
	Gui, % GuiHwnd ":+OwnDialogs"
	msgbox, % "You Pressed The " A_GuiControl " Button"
	MsgButtonPressed := A_GuiControl
	Gui, % A_Gui ":Destroy"
	
	return
;}

;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;Custom Msgbox Function.
customMsgbox( text , title := "" , glabel := "" , options := "+Owner +LastFound" , rectObj := "" , textOptions := " Center 0x200 " , wait := 1 , posObj := "" , UseCancelButton := 0 ){
	static ButtonArea := { MinWidth: 190 , H: 40 } , buttonWidth := 75 , buttonHeight := 22 
	, fontSize := 8 , FontType := "Segoe UI" , FontColor := "000000"
	, BackgroundColor1 := "F0F0F0" , BackgroundColor2 := "FFFFFF"
	Gui, New, % " +HwndGuiHwnd -MinimizeBox -SysMenu " options , % title
	Gui, Margin, 0 , 0
	Gui, Color, % BackgroundColor1
	Gui, Font, s%fontSize% c%FontColor% , % FontType
	if( rectObj.Haskey( "W" ) && rectObj.Haskey( "H" ) ){
		if( rectObj.W < ButtonArea.MinWidth )
			rectObj.W := ButtonArea.MinWidth
		Gui, Add, Progress, % "x0 y0 w" rectObj.W " h" rectObj.H - ButtonArea.H " Background" BackgroundColor2
		Gui, Add, Text, % "x10 y10 w" rectObj.W - 20 " h" rectObj.H - ButtonArea.H - 20 " BackgroundTrans " textOptions , % Text
		DetectHiddenWindows, On
		Gui, Show, Hide AutoSize
		WinGetPos,,, w, h , % "ahk_id " GuiHwnd
		if( glabel ){
			if( UseCancelButton ){
				x1 := w - buttonWidth * 2 - 30
				x2 := w - buttonWidth - 20
				Gui, Add, Button, % "x" x1 " y" rectObj.H - ButtonArea.H + 10 " w" buttonWidth " h" buttonHeight " Default g" glabel , Ok
				Gui, Add, Button, % "x" x2  " y" rectObj.H - ButtonArea.H + 10 " w" buttonWidth " h" buttonHeight " g" glabel , Cancel
			}else{
				Gui, Add, Button, % "x" w - buttonWidth - 20 " y" rectObj.H - ButtonArea.H + 10 " w" buttonWidth " h" buttonHeight " Default g" glabel , Ok
			}
		}else{
			Gui, Add, Button, % "x" w - buttonWidth - 20 " y" rectObj.H - ButtonArea.H + 10 " w" buttonWidth " h" buttonHeight " gCMB1 Default" , Ok
		
		}
	}else{
		Gui, Dummy:Font, s%fontSize% cBlack , % FontType
		Gui, Dummy:Add, Text, , % text
		GuiControlGet, pos, Dummy:pos , static1
		Gui, Dummy:Destroy
		Gui, % GuiHwnd ":Add", Progress, % "x0 y0 w" ( ( posW < 180 ) ? ( 180 + 20 ) : ( posW + 20 ) ) " h" ( ( posH < 40 ) ? ( 40 + 20 ) : ( posH + 20 ) ) " Background" BackgroundColor2 
		Gui, % GuiHwnd ":Add", Text, % "x10 y10 w" ( ( posW < 180 ) ? ( 180 ) : ( posW ) ) " h" ( ( posH < 40 ) ? ( 40 ) : ( posH ) ) " BackgroundTrans " textOptions , % Text
		DetectHiddenWindows, On
		Gui, % GuiHwnd ":Show", Hide AutoSize
		WinGetPos,,, w, h , % "ahk_id " GuiHwnd
		if( glabel ){
			
			if( UseCancelButton ){
				SoundBeep
				x1 := w - buttonWidth * 2 - 30
				x2 := w - buttonWidth - 20
				Gui, Add, Button, % "x" x1 " y" ( ( posH < 40 ) ? ( 40 + 20 + 10 ) : ( posH + 20 + 10 ) ) " w" buttonWidth " h" buttonHeight " Default g" glabel , Ok
				Gui, Add, Button, % "x" x2  " y" ( ( posH < 40 ) ? ( 40 + 20 + 10 ) : ( posH + 20 + 10 ) ) " w" buttonWidth " h" buttonHeight " g" glabel , Cancel
			}else{
				Gui, Add, Button, % "x" w - buttonWidth - 20 " y" ( ( posH < 40 ) ? ( 40 + 20 + 10 ) : ( posH + 20 + 10 ) ) " w" buttonWidth " h" buttonHeight " Default g" glabel , Ok
			}
			
			;~ Gui, % GuiHwnd ":Add", Button, % "x" w - buttonWidth - 20 " y" ( ( posH < 40 ) ? ( 40 + 20 + 10 ) : ( posH + 20 + 10 ) ) " w" buttonWidth " h" buttonHeight " Default g" glabel , Ok
			
		}else{
			Gui, % GuiHwnd ":Add", Button, % "x" w - buttonWidth - 20 " y" ( ( posH < 40 ) ? ( 40 + 20 + 10 ) : ( posH + 20 + 10 ) ) " w" buttonWidth " h" buttonHeight " gCMB1 Default" , Ok
		
		}
	}
	Gui, % GuiHwnd ":Margin", 0 , 10
	if( rectObj.Haskey( "X" ) && rectObj.Haskey( "Y" ) ){
		if( rectObj.X = "Center" && rectObj.Y = "Center" && isObject( posObj ) ){
			WinGetPos,,, w , h , % "ahk_id " GuiHwnd
			x := posObj.X + ( posObj.W - w ) / 2
			y := posObj.Y + ( posObj.H - h ) / 2
			Gui, % GuiHwnd ":Show", % " AutoSize x" X " y" Y 
		}else{
			Gui, % GuiHwnd ":Show", % " AutoSize x" rectObj.X " y" rectObj.Y , % title
		}
	}else
		Gui, % GuiHwnd ":Show", AutoSize
	if( wait )
		WinWaitClose, % "ahk_id " GuiHwnd
	return
	CMB1:
		Gui, % A_Gui ":Destroy"
		return	
}
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|;|<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>||<<<---(0)_(0)--->>>|
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Msgbox always shown in CENTER of parent GUI window

29 Oct 2023, 21:49

GEOVAN wrote: is there a way to "force" msgbox always shown in CENTER of parent GUI window
There is a direct way:

Code: Select all

#Requires AutoHotkey v1

Gui, +Resize
Gui, Add, Button, gShowMsgBox, Show MsgBox
Gui, Show, w500 h300, You can resize me
Return

ShowMsgBox() {
   Gui, %A_Gui%: +OwnDialogs ; <— +OwnDialogs must be set
   MsgBox I will always appear in the center of the parent GUI
}

GuiClose() {
   ExitApp
}

CenterMsgBox(nCode, wp, lp) {
   static WH_CBT := 5, HCBT_CREATEWND := 3
        , dummy := OnExit( Func("CenterMsgBox").Bind("OnExit") )
        , hHook := DllCall("SetWindowsHookEx", "Int", WH_CBT
                                             , "Ptr", RegisterCallback("CenterMsgBox", "Fast")
                                             , "Ptr", 0
                                             , "UInt", DllCall("GetCurrentThreadId"), "Ptr")
   if (nCode = "OnExit")  {
      DllCall("UnhookWindowsHookEx", "Ptr", hHook)
      return
   }
   if (nCode = HCBT_CREATEWND) {
      VarSetCapacity(WinClass, 256)
      DllCall("GetClassName", "Ptr", hwnd := wp, "Str", WinClass, "Int", 256)
      if (WinClass = "#32770") {
         pCREATESTRUCT := NumGet(lp + 0)
         addr := pCREATESTRUCT + A_PtrSize * 4
         if hOwner := NumGet(addr - A_PtrSize) {
            WinGetPos, xo, yo, wo, ho, ahk_id %hOwner%
            wm := NumGet(addr + 4, "Int")
            hm := NumGet(addr + 0, "Int")
            NumPut(xo + (wo - wm) // 2, addr + 12, "Int")
            NumPut(yo + (ho - hm) // 2, addr +  8, "Int")
         }
      }
   }
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wp, "Ptr", lp)
}
User avatar
Hellbent
Posts: 2114
Joined: 23 Sep 2017, 13:34

Re: Msgbox always shown in CENTER of parent GUI window

29 Oct 2023, 22:42

@teadrinker That's really nice. Thanks for sharing it.
:bravo:
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

30 Oct 2023, 00:01

Thank you very very very much!!!
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

05 Nov 2023, 12:44

teadrinker wrote:
29 Oct 2023, 21:49
GEOVAN wrote: is there a way to "force" msgbox always shown in CENTER of parent GUI window
There is a direct way:

Code: Select all

#Requires AutoHotkey v1

Gui, +Resize
Gui, Add, Button, gShowMsgBox, Show MsgBox
Gui, Show, w500 h300, You can resize me
Return

ShowMsgBox() {
   Gui, %A_Gui%: +OwnDialogs ; <— +OwnDialogs must be set
   MsgBox I will always appear in the center of the parent GUI
}

GuiClose() {
   ExitApp
}

CenterMsgBox(nCode, wp, lp) {
   static WH_CBT := 5, HCBT_CREATEWND := 3
        , dummy := OnExit( Func("CenterMsgBox").Bind("OnExit") )
        , hHook := DllCall("SetWindowsHookEx", "Int", WH_CBT
                                             , "Ptr", RegisterCallback("CenterMsgBox", "Fast")
                                             , "Ptr", 0
                                             , "UInt", DllCall("GetCurrentThreadId"), "Ptr")
   if (nCode = "OnExit")  {
      DllCall("UnhookWindowsHookEx", "Ptr", hHook)
      return
   }
   if (nCode = HCBT_CREATEWND) {
      VarSetCapacity(WinClass, 256)
      DllCall("GetClassName", "Ptr", hwnd := wp, "Str", WinClass, "Int", 256)
      if (WinClass = "#32770") {
         pCREATESTRUCT := NumGet(lp + 0)
         addr := pCREATESTRUCT + A_PtrSize * 4
         if hOwner := NumGet(addr - A_PtrSize) {
            WinGetPos, xo, yo, wo, ho, ahk_id %hOwner%
            wm := NumGet(addr + 4, "Int")
            hm := NumGet(addr + 0, "Int")
            NumPut(xo + (wo - wm) // 2, addr + 12, "Int")
            NumPut(yo + (ho - hm) // 2, addr +  8, "Int")
         }
      }
   }
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wp, "Ptr", lp)
}
Many many thanks teaDrinker!!!
This is exactly what we were looking.

STEP 1:
Just before each msgbox we add the Gui +OwnDialogs

STEP 2:
And at the end of the script we just add your "miraculous code", that is :

Code: Select all

CenterMsgBox(nCode, wp, lp) {
   static WH_CBT := 5, HCBT_CREATEWND := 3
        , dummy := OnExit( Func("CenterMsgBox").Bind("OnExit") )
        , hHook := DllCall("SetWindowsHookEx", "Int", WH_CBT
                                             , "Ptr", RegisterCallback("CenterMsgBox", "Fast")
                                             , "Ptr", 0
                                             , "UInt", DllCall("GetCurrentThreadId"), "Ptr")
   if (nCode = "OnExit")  {
      DllCall("UnhookWindowsHookEx", "Ptr", hHook)
      return
   }
   if (nCode = HCBT_CREATEWND) {
      VarSetCapacity(WinClass, 256)
      DllCall("GetClassName", "Ptr", hwnd := wp, "Str", WinClass, "Int", 256)
      if (WinClass = "#32770") {
         pCREATESTRUCT := NumGet(lp + 0)
         addr := pCREATESTRUCT + A_PtrSize * 4
         if hOwner := NumGet(addr - A_PtrSize) {
            WinGetPos, xo, yo, wo, ho, ahk_id %hOwner%
            wm := NumGet(addr + 4, "Int")
            hm := NumGet(addr + 0, "Int")
            NumPut(xo + (wo - wm) // 2, addr + 12, "Int")
            NumPut(yo + (ho - hm) // 2, addr +  8, "Int")
         }
      }
   }
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wp, "Ptr", lp)
}
Please let me ask regarding the miraculous code :
Because i am new in AHK, i can not follow what exactly the miraculous code "says", because is very complicated for me to understand it, so please let me ask:
The miraculous code is a kind of AHK LIBRARY, that is why it is very long?
Is it safe to use in any script, or it will interact in any way with other scripts or other programs running at the same time?
The ONLY thing the miraculous code do is ------> to center msgboxes (that are "Gui +OwnDialogs") WHICH will be "called" ONLY by the script that CONTAINS the miraculous code ?
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Msgbox always shown in CENTER of parent GUI window

06 Nov 2023, 08:40

GEOVAN wrote: i can not follow what exactly the miraculous code "says"
This code does the following: every time the script creates a new window, it first checks which class (ahk_class) the window belongs to; if the window belongs to class #32770 (MessageBox, but also some other windows, for example, InputBox), it checks if the window has an owner; if an owner is assigned, the window's coordinates are changed.
GEOVAN wrote: The miraculous code is a kind of AHK LIBRARY
No, this code itself is not a library, it is just a function. A library usually means some code located in a separate file and used in the main code using the #Include directive. If you put this code in a separate file, then it will be a library.
GEOVAN wrote: that is why it is very long?
I assure you, there are much longer libraries, you can see for yourself if you go to the Scripts and Functions section.
GEOVAN wrote: Is it safe to use in any script
Yes, it is perfectly safe to use it, except for the fact that it can, as mentioned above, affect some other windows as well.
GEOVAN wrote: it will interact in any way with other scripts or other programs running at the same time?
No, this code can only affect windows that belong only to the current script's process.
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

06 Nov 2023, 12:15

Thank you very very much for helping us!!!
Please let clarify only one last point:
teadrinker wrote:
06 Nov 2023, 08:40
GEOVAN wrote: Is it safe to use in any script
Yes, it is perfectly safe to use it, except for the fact that it can, as mentioned above, affect some other windows as well.
By saying --->
.... it can affect some other windows you mean ONLY the windows that will be called by the running script which contains the miracle code, like for example "inputbox , msgbox, etc" , AND only affects these windows if they have an owner [ that is before them we add ----> Gui +OwnDialogs , (( or Gui MyGui: +OwnDialogs -- where MyGui is the name of the Gui )) ].
AND
These windows in order to be affected MUST be "CALLED" ONLY by the running script which contains the miracle code. (Other scripts that may running at the same time with the script that contains the miracle code, and may call their msgbox or inputbox etc, these windows will NOT be affected by the miracle code, since their script does not contains the miracle code).

Do i understand it correct, please?
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

27 Jan 2024, 14:20

teadrinker wrote:
29 Oct 2023, 21:49
GEOVAN wrote: is there a way to "force" msgbox always shown in CENTER of parent GUI window
There is a direct way:

Code: Select all

#Requires AutoHotkey v1

Gui, +Resize
Gui, Add, Button, gShowMsgBox, Show MsgBox
Gui, Show, w500 h300, You can resize me
Return

ShowMsgBox() {
   Gui, %A_Gui%: +OwnDialogs ; <— +OwnDialogs must be set
   MsgBox I will always appear in the center of the parent GUI
}

GuiClose() {
   ExitApp
}

CenterMsgBox(nCode, wp, lp) {
   static WH_CBT := 5, HCBT_CREATEWND := 3
        , dummy := OnExit( Func("CenterMsgBox").Bind("OnExit") )
        , hHook := DllCall("SetWindowsHookEx", "Int", WH_CBT
                                             , "Ptr", RegisterCallback("CenterMsgBox", "Fast")
                                             , "Ptr", 0
                                             , "UInt", DllCall("GetCurrentThreadId"), "Ptr")
   if (nCode = "OnExit")  {
      DllCall("UnhookWindowsHookEx", "Ptr", hHook)
      return
   }
   if (nCode = HCBT_CREATEWND) {
      VarSetCapacity(WinClass, 256)
      DllCall("GetClassName", "Ptr", hwnd := wp, "Str", WinClass, "Int", 256)
      if (WinClass = "#32770") {
         pCREATESTRUCT := NumGet(lp + 0)
         addr := pCREATESTRUCT + A_PtrSize * 4
         if hOwner := NumGet(addr - A_PtrSize) {
            WinGetPos, xo, yo, wo, ho, ahk_id %hOwner%
            wm := NumGet(addr + 4, "Int")
            hm := NumGet(addr + 0, "Int")
            NumPut(xo + (wo - wm) // 2, addr + 12, "Int")
            NumPut(yo + (ho - hm) // 2, addr +  8, "Int")
         }
      }
   }
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wp, "Ptr", lp)
}


Hello, please HELP:
If MINIMIZED the window, then when the msgbox comes, NOTHING appears, and it FREEZE the GUI window after maximized it.
To understand what i mean i ADD a timeout 5 seconds , in order to can manually minimized the GUI window after you click the button.....
Please help how to overcome this error:

Code: Select all

Gui, +Resize
Gui, Add, Button, gShowMsgBox, Show MsgBox
Gui, Show, w500 h300, You can resize me
Return

ShowMsgBox() {
   runwait, timeout 5
   Gui, %A_Gui%: +OwnDialogs ; <— +OwnDialogs must be set
   MsgBox I will always appear in the center of the parent GUI
}

GuiClose() {
   ExitApp
}

CenterMsgBox(nCode, wp, lp) {
   static WH_CBT := 5, HCBT_CREATEWND := 3
        , dummy := OnExit( Func("CenterMsgBox").Bind("OnExit") )
        , hHook := DllCall("SetWindowsHookEx", "Int", WH_CBT
                                             , "Ptr", RegisterCallback("CenterMsgBox", "Fast")
                                             , "Ptr", 0
                                             , "UInt", DllCall("GetCurrentThreadId"), "Ptr")
   if (nCode = "OnExit")  {
      DllCall("UnhookWindowsHookEx", "Ptr", hHook)
      return
   }
   if (nCode = HCBT_CREATEWND) {
      VarSetCapacity(WinClass, 256)
      DllCall("GetClassName", "Ptr", hwnd := wp, "Str", WinClass, "Int", 256)
      if (WinClass = "#32770") {
         pCREATESTRUCT := NumGet(lp + 0)
         addr := pCREATESTRUCT + A_PtrSize * 4
         if hOwner := NumGet(addr - A_PtrSize) {
            WinGetPos, xo, yo, wo, ho, ahk_id %hOwner%
            wm := NumGet(addr + 4, "Int")
            hm := NumGet(addr + 0, "Int")
            NumPut(xo + (wo - wm) // 2, addr + 12, "Int")
            NumPut(yo + (ho - hm) // 2, addr +  8, "Int")
         }
      }
   }
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wp, "Ptr", lp)
}
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Msgbox always shown in CENTER of parent GUI window

27 Jan 2024, 15:22

Hello!
Where should MsgBox appear if the window is minimized?
GEOVAN
Posts: 192
Joined: 03 Mar 2022, 11:12

Re: Msgbox always shown in CENTER of parent GUI window

27 Jan 2024, 16:04

teadrinker wrote:
27 Jan 2024, 15:22
Hello!
Where should MsgBox appear if the window is minimized?
When GUI window is minimized, i want also the MSGBOX to be minimized, and when i manually maximized the GUI window, to show the GUI window AND the MSGBOX.
But unfortunately now it shows ONLY the GUI window FREEZED, and i must use task manager to force close it.

Please, is there any way to solve this?
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Msgbox always shown in CENTER of parent GUI window

28 Jan 2024, 10:21

Maybe like this:

Code: Select all

#Requires AutoHotkey v1

Gui, New, +Resize +hwndhGui
Gui, Add, Button, gShowMsgBox, Minimize and show MsgBox
Gui, Show, w500 h300, You can resize me
Return

ShowMsgBox() {
   Gui, %A_Gui%: +OwnDialogs ; <— +OwnDialogs must be set
   WinMinimize, ahk_id %A_Gui%
   Sleep 100
   MsgBox I will always appear in the center of the parent GUI
}

GuiClose() {
   ExitApp
}

CenterMsgBox(nCode, wp, lp) {
   static WH_CBT := 5, HCBT_CREATEWND := 3, SW_SHOWMINIMIZED := 2
        , EVENT_SYSTEM_MINIMIZEEND := 0x0017, EVENT_OBJECT_CREATE := 0x8000
        , dummy := OnExit( Func("CenterMsgBox").Bind("OnExit") )
        , hHook := DllCall("SetWindowsHookEx", "Int", WH_CBT
                                             , "Ptr", RegisterCallback("CenterMsgBox", "Fast")
                                             , "Ptr", 0
                                             , "UInt", DllCall("GetCurrentThreadId"), "Ptr")
   if (nCode = "OnExit")  {
      DllCall("UnhookWindowsHookEx", "Ptr", hHook)
      return
   }
   if (nCode = HCBT_CREATEWND) {
      VarSetCapacity(WinClass, 256)
      DllCall("GetClassName", "Ptr", hwnd := wp, "Str", WinClass, "Int", 256)
      if (WinClass = "#32770") {
         pCREATESTRUCT := NumGet(lp + 0)
         addr := pCREATESTRUCT + A_PtrSize * 4
         if hOwner := NumGet(addr - A_PtrSize) {
            VarSetCapacity(WINDOWPLACEMENT, 44, 0)
            DllCall("GetWindowPlacement", "Ptr", hOwner, "Ptr", &WINDOWPLACEMENT)
            showCmd := NumGet(WINDOWPLACEMENT, 8, "UInt")
            xo := NumGet(WINDOWPLACEMENT, 28, "Int")
            yo := NumGet(WINDOWPLACEMENT, 32, "Int")
            wo := NumGet(WINDOWPLACEMENT, 36, "Int") - xo
            ho := NumGet(WINDOWPLACEMENT, 40, "Int") - yo
            wm := NumGet(addr + 4, "Int")
            hm := NumGet(addr + 0, "Int")
            NumPut(xo + (wo - wm) // 2, addr + 12, "Int")
            NumPut(yo + (ho - hm) // 2, addr +  8, "Int")
            if (showCmd = SW_SHOWMINIMIZED) {
               PID := DllCall("GetCurrentProcessId")
               for event, id in {(EVENT_OBJECT_CREATE): hwnd, (EVENT_SYSTEM_MINIMIZEEND): hOwner} {
                  SetWinEventHook(event, event, 0, RegisterCallback("HookProc", "F",, id), PID, 0, 0)
               }
            }
         }
      }
   }
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wp, "Ptr", lp)
}

HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
   static EVENT_SYSTEM_MINIMIZEEND := 0x0017, EVENT_OBJECT_CREATE := 0x8000, hMsg := ""
   if (hwnd != A_EventInfo) {
      Return
   }
   switch event {
      case EVENT_OBJECT_CREATE:
         hMsg := hwnd
         while !DllCall("IsWindowVisible", "Ptr", hMsg) {
            continue
         }
         WinHide, ahk_id %hMsg%
      case EVENT_SYSTEM_MINIMIZEEND: WinShow, ahk_id %hMsg%
   }
   DllCall("UnhookWinEvent", "Ptr", hWinEventHook)
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)
{
   Return DllCall("SetWinEventHook", "UInt", eventMin, "UInt", eventMax
                                   , "Ptr", hmodWinEventProc, "Ptr", lpfnWinEventProc
                                   , "UInt", idProcess, "UInt", idThread, "UInt", dwFlags, "Ptr")
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: peter_ahk and 353 guests