MattyD Posted 5 hours ago Posted 5 hours ago Hi all, I've been having a play around today and thought someone might find it interesting. Basically you can define a dialog template, and with that you can create modal windows outside of the ones provided by MsgBox & InputBox. Theoretically these can also be added to compiled scripts as resources - but that'll be the next thing to sus out! You'll see "Script Activity!" is continuously written to the console - but this stops with the "About" window open. (DialogBoxIndirectParam doesn't return until EndDialog is called). DialogBoxIndirectParam will also return different codes depending on which button you push Its also worth noting, the dialog coords are in "Dialog Units" - not pixels. These base values apparently change depending on scaling and the typeface selected. So controls can be a bit squidgy placement wise, but it should help with legibility across a range of different setups. If you believe the internet anyway! expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ;#AutoIt3Wrapper_UseX64=N #include <WinAPISys.au3> #include <WinAPISysWin.au3> #include <GuiConstants.au3> #include <WindowsConstants.au3> #include <FontConstants.au3> #include <GuiMenu.au3> Global Const $tagDLGTEMPLATEEX_Base = "struct;" & _ "word dlgVer;" & _ "word signature;" & _ "dword helpID;" & _ "dword exStyle;" & _ "dword style;" & _ "word cDlgItems;" & _ "short x;" & _ "short y;" & _ "short cx;" & _ "short cy;" & _ "word menu[%d];" & _ "word windowClass[%d];" & _ "wchar title[%d];" & _ "word pointsize;" & _ "word weight;" & _ "byte italic;" & _ "byte charset;" & _ "wchar typeface[%d];" & _ "endstruct;" & _ "align 4;" Global Const $tagDLGITEMTEMPLATEEX_Base = "struct;" & _ "dword helpID;" & _ "dword exStyle;" & _ "dword style;" & _ "short x;" & _ "short y;" & _ "short cx;" & _ "short cy;" & _ "dword id;" & _ "word windowClass[%d];" & _ "wchar title[%d];" & _ "word extraCount;" & _ "endstruct;" Global Const $IDM_ABOUT = 104, $IDM_EXIT = 105 Global $hGUI, $hDlgProc, $pDlgProc Example() Func Example() $hDlgProc = DllCallbackRegister("DlgProc", "int_ptr", "hwnd;uint;wparam;lparam") $pDlgProc = DllCallbackGetPtr($hDlgProc) $hGUI = GUICreate("Example GUI", 400, 200) GUICtrlCreateLabel("Goto: Help > About to launch the dialog.", 10, 60, 380, 20, BitOR($SS_CENTERIMAGE, $SS_CENTER)) GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Local $hMainMenu = _GUICtrlMenu_CreateMenu() _GUICtrlMenu_SetMenu($hGUI, $hMainMenu) Local $hFileMenu = _GUICtrlMenu_CreateMenu() _GUICtrlMenu_AppendMenu($hFileMenu, $MF_ENABLED, $IDM_EXIT, "E&xit") Local $hHelpMenu = _GUICtrlMenu_CreateMenu() _GUICtrlMenu_AppendMenu($hHelpMenu, $MF_ENABLED, $IDM_ABOUT, "&About") _GUICtrlMenu_InsertMenuItem($hMainMenu, 0, "&File", 0, $hFileMenu) _GUICtrlMenu_InsertMenuItem($hMainMenu, 1, "&Help", 0, $hHelpMenu) _GUICtrlMenu_DrawMenuBar($hGUI) GUISetState() Local $hTimer = TimerInit() Do If TimerDiff($hTimer) > 1000 Then ConsoleWrite("Scipt Activity!" & @CRLF) $hTimer = TimerInit() EndIf Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIRegisterMsg($WM_COMMAND, "") GUIDelete($hGUI) DllCallbackFree($hDlgProc) EndFunc ;==>Example Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Switch _WinAPI_LoWord($wParam) Case $IDM_EXIT _WinAPI_PostMessage($hWnd, $WM_SYSCOMMAND, $SC_CLOSE, 0) Case $IDM_ABOUT Local $tDialog = CreateDlg("About", "Hello World!!") Local $aCall = DllCall("User32.dll", "int_ptr", "DialogBoxIndirectParamW", "handle", 0, "struct*", $tDialog, "hwnd", $hWnd, "ptr", $pDlgProc, "dword", 0) ConsoleWrite("Return: " & $aCall[0] & @CRLF) _WinAPI_SetActiveWindow($hWnd) EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND Func DlgProc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $WM_SYSCOMMAND If BitAND(0xFFF0, $wParam) = $SC_CLOSE Then DllCall("User32.dll", "bool", "EndDialog", "hwnd", $hWnd, "int_ptr", $IDCANCEL) Return 0 EndIf Case $WM_COMMAND Switch _WinAPI_LoWord($wParam) Case $IDOK, $IDCANCEL DllCall("User32.dll", "bool", "EndDialog", "hwnd", $hWnd, "int_ptr", $wParam) Return 0 EndSwitch EndSwitch Return _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam) EndFunc Func CreateDlg($sTitle, $sMessage) Local $sTypeFace = "MS Shell Dlg" Local $tagDLGTEMPLATEEX = StringFormat($tagDLGTEMPLATEEX_Base, _ 1, 1, _ StringLen($sTitle) + 1, _ StringLen($sTypeFace) + 1) Local $iItemCnt = 3 Local $asTitles = [$sMessage, "OK", "Cancel"] Local $tDlgTemplateItem, $tagDLGTEMPLATEITEMEX For $i = 1 To $iItemCnt $tagDLGTEMPLATEITEMEX = StringFormat($tagDLGITEMTEMPLATEEX_Base, 2, StringLen($asTitles[$i - 1]) + 1) $tDlgTemplateItem = DllStructCreate($tagDLGTEMPLATEITEMEX) $tagDLGTEMPLATEEX &= StringFormat("byte item%d[%d];", $i, DllStructGetSize($tDlgTemplateItem)) Next Local $tDlgTemplate = DllStructCreate($tagDLGTEMPLATEEX) ;Header $tDlgTemplate.dlgVer = 1 $tDlgTemplate.signature = 0xFFFF $tDlgTemplate.helpID = 0 $tDlgTemplate.exStyle = $WS_EX_DLGMODALFRAME $tDlgTemplate.Style = BitOR($WS_POPUP, $WS_CAPTION, $WS_SYSMENU, $DS_MODALFRAME, $DS_SETFONT) $tDlgTemplate.cDlgItems = $iItemCnt $tDlgTemplate.x = 0 $tDlgTemplate.y = 0 $tDlgTemplate.cx = 200 $tDlgTemplate.cy = 100 $tDlgTemplate.title = $sTitle $tDlgTemplate.pointsize = 8 $tDlgTemplate.weight = $FW_NORMAL $tDlgTemplate.italic = False $tDlgTemplate.charset = $DEFAULT_CHARSET $tDlgTemplate.typeface = $sTypeFace For $i = 1 To $iItemCnt $tagDLGTEMPLATEITEMEX = StringFormat($tagDLGITEMTEMPLATEEX_Base, 2, StringLen($asTitles[$i - 1]) + 1) $tDlgTemplateItem = DllStructCreate($tagDLGTEMPLATEITEMEX, DllStructGetPtr($tDlgTemplate, "item" & $i)) Switch $i Case 1 ;Label $tDlgTemplateItem.windowClass(1) = 0xFFFF ;Label $tDlgTemplateItem.windowClass(2) = 0x0082 $tDlgTemplateItem.title = $asTitles[$i - 1] $tDlgTemplateItem.x = 10 $tDlgTemplateItem.y = 20 $tDlgTemplateItem.cx = 180 $tDlgTemplateItem.cy = 20 $tDlgTemplateItem.Style = BitOR($SS_CENTERIMAGE, $SS_LEFT, $WS_VISIBLE, $WS_CHILD) $tDlgTemplateItem.exStyle = $WS_EX_WINDOWEDGE Case 2 ;OK Button $tDlgTemplateItem.windowClass(1) = 0xFFFF $tDlgTemplateItem.windowClass(2) = 0x0080 $tDlgTemplateItem.id = $IDOK $tDlgTemplateItem.title = $asTitles[$i - 1] $tDlgTemplateItem.x = 90 $tDlgTemplateItem.y = 75 $tDlgTemplateItem.cx = 50 $tDlgTemplateItem.cy = 20 $tDlgTemplateItem.Style = BitOR($BS_CENTER, $BS_VCENTER, $WS_TABSTOP, $WS_VISIBLE, $WS_CHILD) $tDlgTemplateItem.exStyle = $WS_EX_WINDOWEDGE Case 3 ;Cancel Button $tDlgTemplateItem.windowClass(1) = 0xFFFF $tDlgTemplateItem.windowClass(2) = 0x0080 $tDlgTemplateItem.id = $IDCANCEL $tDlgTemplateItem.title = $asTitles[$i - 1] $tDlgTemplateItem.x = 145 $tDlgTemplateItem.y = 75 $tDlgTemplateItem.cx = 50 $tDlgTemplateItem.cy = 20 $tDlgTemplateItem.Style = BitOR($BS_CENTER, $BS_VCENTER, $WS_TABSTOP, $WS_VISIBLE, $WS_CHILD) $tDlgTemplateItem.exStyle = $WS_EX_WINDOWEDGE EndSwitch Next Return $tDlgTemplate EndFunc argumentum 1
MattyD Posted 4 hours ago Author Posted 4 hours ago Actually, embedding the dialog isn't too difficult once we have it defined: Compile ShowDlg.au3 Run AddDlgRes.au3 to add the dialog to ShowDlg.exe's resources (ShowDlg.exe must be in the same folder as AddDlgRes.au3) Run ShowDlg.exe > Help > About. DialogRes.zip WildByDesign 1
WildByDesign Posted 3 hours ago Posted 3 hours ago This is really neat, Matty. Thanks for sharing it. I think that this could be incredibly useful to be able to have custom dialogs instead of the typical system MsgBox. This opens up quite a bit of possibilities. I've been messing around with this script for about an hour trying various things and it is tempting me to implement it in some of my older GUI projects now. I do have a question and it's something that will likely come up at some point. How easy or difficult would it be to implement adding a background color to the dialog box?
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now