kashamalasha

Place child elements inside parents

6 posts in this topic

Hi, guys.

Could you help me to understand how to place child elements like MsgBox, InputBox etc. inside parent element?

I want to set padding from top border of $hMainGui equal 20px and from left border equal 20px. Is it possible? Thanks in advance.

 

PlaceMsgBox.png

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

#include <MsgBoxConstants.au3>

Local $iPadding = 20
Local $mainUiHeight = 420
Local $mainUiWidth = 800
Local $hGUI = GUICreate ( "GUI", $mainUiWidth, $mainUiHeight, -1, -1 )
GUISetState (@SW_SHOW)

; Retrieve the position x, y and size (width and height) of the control
Local $aPos = WinGetPos ( $hGUI )

; Display the position and size of the edit control.
MsgBox ( $MB_SYSTEMMODAL, "Parent $hGUI", "Position: " & $aPos[0] & ", " & $aPos[1] & @CRLF & "Size: " & $aPos[2] & ", " & $aPos[3] )

; Test Input box within Parent Window ( $iPadding 20 )
Local $sAnswer = InputBox("Question", "Where were you born?", "Planet Earth", "", Default, Default, $aPos[0] + $iPadding, $aPos[1] + $iPadding, 0)

Exit 0

I have not very much experience with this. (i never had any use for it). But the question sounds interesting and i think the answer can be useful for others too. Anyway i tried some things and the above code comes close to what you want. a bit weird is that $mainUiHeight / $mainUiWidth is not exactly the values represented by $aPos[]

Edited by pluto41

Share this post


Link to post
Share on other sites

Nope. It doesn't work. Try to move your $hGUI window between the events. You will see that InputBox will appear with the wrong coordinates, regardless parent window.

Share this post


Link to post
Share on other sites

After every event you have to read $aPos = WinGetPos ( $hGUI ) again. I can't see why that would work.. But i admit there is probably a better solution. I will follow the topic for other suggestions :)

Share this post


Link to post
Share on other sites

IC. I'll try to add WinGetPos before every InputBox in my code.

Thanks.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

So I've looked into it and it is indeed possible, though i argue not worth the effort.

From what i found via google there's 2 ways to center inputbox and msgbox, source: How do I change the MessageBox location?

I made a crude example with the hook method:

#include <WinAPI.au3>
#include <WinAPIDiag.au3>

$HCBT_ACTIVATE = 5

Opt("GuiOnEventMode", 1)
$hWnd = GUICreate("", 700, 320)
GUISetOnEvent(-3, "_MyExit", $hWnd)

GUICtrlCreateButton("MsgBox", 10, 10)
GUICtrlSetOnEvent(-1, "_MsgBox")
GUICtrlCreateButton("InputBox", 10, 40)
GUICtrlSetOnEvent(-1, "_InputBox")

;~ $hProg = DllCallbackGetPtr(
$pProg = DllCallbackRegister("WH_CBT", "LONG_PTR", "INT;UINT_PTR;LONG_PTR")

GUISetState()

While 1
    Sleep(10)
WEnd

Func _MyExit()
    DllCallbackFree($pProg)
    Exit
EndFunc

Func _InputBox()
    Local $hHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($pProg), Null, _WinAPI_GetCurrentThreadId())
    InputBox("title", "promt", "default")
    _WinAPI_UnhookWindowsHookEx($hHook)
EndFunc

Func _MsgBox()
    Local $hHook = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($pProg), Null, _WinAPI_GetCurrentThreadId())
    MsgBox(0, "Title", "Message")
    _WinAPI_UnhookWindowsHookEx($hHook)
EndFunc

;~ When the message box is about to be shown,
;~ centre the dialog
Func WH_CBT($uMsg, $wParam, $lParam)
    If $uMsg < 0 Then
        Return _WinAPI_CallNextHookEx($hHook, $uMsg, $wParam, $lParam)
    EndIf
    Local $tagCBTACTIVATESTRUCT = "BOOL fMouse;HWND hWndActive"
    If ( $uMsg = $HCBT_ACTIVATE ) And ( Not ( $wParam = $hWnd ) ) Then
;~      in a HCBT_ACTIVATE message, wParam holds
;~      the handle to the messagebox
        Local $hwndMsgBox = $wParam

        Local $tCBTACTIVATESTRUCT = DllStructCreate($tagCBTACTIVATESTRUCT, $lParam)

;~      Just as was done in other API hook demos,
;~      position the dialog centered in the calling
;~      parent form
        Local $rc = _WinAPI_GetWindowRect($hwndMsgBox)
        Local $rc2 = _WinAPI_GetWindowRect($hWnd)
        $dlgWidth = $rc.Right - $rc.Left
        $dlgHeight = $rc.Bottom - $rc.Top
        $newLeft = $rc2.Left + ( ($rc2.Right - $rc2.Left)/2 - $dlgWidth/2 )
        $newTop = $rc2.Top + ( ($rc2.Bottom - $rc2.Top)/2 - $dlgHeight/2 )

        _WinAPI_MoveWindow($hwndMsgBox, $newLeft, $newTop, $dlgWidth, $dlgHeight)
    EndIf

;~  return False to let normal
;~  processing continue
    Return False
EndFunc

The above code was parsed mostly from: SetWindowsHookEx: Centre the API Message Box

Also i found a possible other option using TaskDialogIndirect, but couldn't find it used in a autoit related thread and long story short i got sidetracked converting TASKDIALOGCONFIG structure to autoit dllstruct

 

Anyway i hope some of this was useful to someone, especially @kashamalasha

Credits to: MSDN, SetWindowsHookEx: Centre the API Message Box and _WinAPI_SetWindowsHookEx Example

 

Edit:

I made TaskDialogIndirect work. Special Thanks to @Danyfirex for the conversion of the TASKDIALOGCONFIG structure

#include <WinAPI.au3>
#include <WinAPIDiag.au3>
#include <WinAPISys.au3>

$HCBT_ACTIVATE = 5

Opt("GuiOnEventMode", 1)
$hWnd = GUICreate("", 700, 320)
GUISetOnEvent(-3, "_MyExit", $hWnd)

GUICtrlCreateButton("TaskDialog", 10, 70)
GUICtrlSetOnEvent(-1, "_TaskDialog")

GUISetState()

While 1
    Sleep(10)
WEnd

Func _MyExit()
    Exit
EndFunc

Func _TaskDialog()
    Local $TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000;vista and above, see: https://msdn.microsoft.com/en-us/library/gg157196.aspx

    Local $TDCBF_OK_BUTTON = 0x0001
    Local $TDCBF_YES_BUTTON = 0x0002
    Local $TDCBF_NO_BUTTON = 0x0004
    Local $TDCBF_CANCEL_BUTTON = 0x0008
    Local $TDCBF_RETRY_BUTTON = 0x0010
    Local $TDCBF_CLOSE_BUTTON = 0x0020
    
    Local $tagTASKDIALOGCONFIG = "uint cbSize;hwnd hwndParent;handle hInstance;int dwFlags;int dwCommonButtons;ptr pszWindowTitle; ptr hMainIcon_pszMainIcon;ptr pszMainInstruction;ptr pszContent;uint cButtons;ptr pButtons;int nDefaultButton;uint cRadioButtons;ptr pRadioButtons;int nDefaultRadioButton;ptr pszVerificationText;ptr pszExpandedInformation;ptr pszExpandedControlText;ptr pszCollapsedControlText;ptr hFooterIcon_pszFooterIcon;ptr pszFooter;ptr pfCallback;LONG_PTR lpCallbackData;uint cxWidth;"
    Local $tagTASKDIALOG_BUTTON = "int nButtonID;ptr pszButtonText"
    Local $tTASKDIALOGCONFIG = DllStructCreate($tagTASKDIALOGCONFIG)
        $tTASKDIALOGCONFIG.cbSize = DllStructGetSize($tTASKDIALOGCONFIG)
        $tTASKDIALOGCONFIG.hwndParent = $hWnd
        $tTASKDIALOGCONFIG.hInstance = Null
        $tTASKDIALOGCONFIG.dwFlags = $TDF_POSITION_RELATIVE_TO_WINDOW
        $tTASKDIALOGCONFIG.dwCommonButtons = $TDCBF_OK_BUTTON
        $tTASKDIALOGCONFIG.pszWindowTitle = Null
        $tTASKDIALOGCONFIG.hMainIcon_pszMainIcon = Null
        $tTASKDIALOGCONFIG.pszMainInstruction = _WinAPI_CreateString("string to be used for the main instruction")
        $tTASKDIALOGCONFIG.pszContent = _WinAPI_CreateString("the dialog's primary content")
        $tTASKDIALOGCONFIG.cButtons = 0
        $tTASKDIALOGCONFIG.pButtons = 0; change ptr in type to STRUCT*
        $tTASKDIALOGCONFIG.nDefaultButton = $IDOK
        $tTASKDIALOGCONFIG.cRadioButtons = 0
        $tTASKDIALOGCONFIG.pRadioButtons = 0; change ptr in type to STRUCT*
        $tTASKDIALOGCONFIG.nDefaultRadioButton = 0
        $tTASKDIALOGCONFIG.pszVerificationText = _WinAPI_CreateString("string to be used to label the verification checkbox")
        $tTASKDIALOGCONFIG.pszExpandedInformation = _WinAPI_CreateString("string to be used for displaying additional information")
        $tTASKDIALOGCONFIG.pszExpandedControlText = _WinAPI_CreateString("string to be used to label the button for collapsing the expandable information")
        $tTASKDIALOGCONFIG.pszCollapsedControlText = _WinAPI_CreateString("string to be used to label the button for expanding the expandable information")
        $tTASKDIALOGCONFIG.hFooterIcon_pszFooterIcon = Null
        $tTASKDIALOGCONFIG.pszFooter = _WinAPI_CreateString("string to be used in the footer area of the task dialog");<A HREF="executablestring">Hyperlink Text</A>    Warning  Enabling hyperlinks when using content from an unsafe source may cause security vulnerabilities.
        $tTASKDIALOGCONFIG.pfCallback = 0;Pointer to an application-defined callback function. For more information see TaskDialogCallbackProc
        $tTASKDIALOGCONFIG.lpCallbackData = 0;A pointer to application-defined reference data. This value is defined by the caller.
        $tTASKDIALOGCONFIG.cxWidth = 0;The width of the task dialog's client area, in dialog units. If 0, the task dialog manager will calculate the ideal width.
    Local $aReutn = DllCall("Comctl32.dll", "LONG", "TaskDialogIndirect", "STRUCT*", $tTASKDIALOGCONFIG, "INT*", 0, "INT*", 0, "BOOL*", 0)
EndFunc

 

Edited by genius257
1 person likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now