Sign in to follow this  
Followers 0
Mat

DialogBoxParam / DialogBox

6 posts in this topic

#1 ·  Posted (edited)

The following code probably doesn't work in lots of different places, but the error I am stuck on now is rather strange and I haven't seen it before. More worrying though is the lack of anywhere to find a decent error message...

AutoIt is crashing on the the Dllcall in my _WinApi_DialogBox function. Trying to use reshacker on the added resource results only in 5 messages saying "Creation data included with compiled dialog will be lost if the file is saved!" followed by another message saying "Access violation at address 004511C3 in module 'reshacker.exe'. Read of address 01BC7128." googling the first is useless and googling the second even more so. In the end it doesn't show the dialog resource. Furthermore, the resource has a size of 666 rather scary when you think that it is a resource that I've copied from AutoIt for the purpose.

Replace.txt:

DLG DIALOGEX 0, 0, 162, 95
STYLE DS_FIXEDSYS | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
CAPTION "AutoIt Input Box"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
FONT 8, "MS Shell Dlg"
{
   CONTROL "Prompt", 1002, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 7, 147, 44
   CONTROL "", 1001, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 7, 56, 147, 12
   CONTROL "OK", 1, BUTTON, BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 16, 73, 50, 14
   CONTROL "Cancel", 2, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 87, 73, 50, 14
}

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_File_Add=replace.txt,RT_DIALOG,DLG
#AutoIt3Wrapper_Run_After="%out%"
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include<WinApi.au3>
#include<WindowsConstants.au3>

Global Const $IDOK = 1
Global Const $IDCANCEL = 2
Global Const $IDABORT = 3
Global Const $IDRETRY = 4
Global Const $IDIGNORE = 5
Global Const $IDYES = 6
Global Const $IDNO = 7

$hGUI = GUICreate("Parent")
GUISetState()

MsgBox(0, _WinApi_DialogBox("DLG", "DlgProc", $hGUI), _WinAPI_GetLastErrorMessage())

Func DlgProc($hWnd, $iMsg, $wParam, $lParam)
    switch ($iMsg)
        case $WM_INITDIALOG
            return TRUE
        case $WM_COMMAND
            switch (_WinAPI_LoWord($wParam))
                case $IDOK
                    _WinAPI_EndDialog($hwnd, $wParam)
                    return TRUE
                case $IDCANCEL
                    _WinAPI_EndDialog($hwnd, $wParam)
                    return TRUE
            EndSwitch
    EndSwitch

    return FALSE
EndFunc

Func _WinAPI_EndDialog($hwndDlg, $wParam)
    Local $aRet = DllCall("User32.dll", "int", "EndDialog", "hwnd", $hwndDlg, "long", $wParam)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aRet[0] <> 0
EndFunc

Func _WinApi_DialogBox($vTemplate, $sDialogFunc, $hWndParent)
    Local $tFunc, $pFunc, $i, $hInstance, $aRet

    ; Callback function
    $tFunc = DllCallbackRegister($sDialogFunc, "int", "hwnd;uint;long;long")
    $pFunc = DllCallbackGetPtr($tFunc)

    $hInstance = _WinAPI_GetModuleHandle(0)

    $aRet = DllCall("User32.dll", "long", "DialogBoxParamW", "handle", $hInstance, "wstr", $vTemplate, "hwnd", $hWndParent, "ptr", $pFunc, "long", 42)
    If @error Then Return SetError(@error, @extended, 0)

    DllCallbackFree($tFunc)

    Return $aRet[0]
EndFunc

Any ideas? This will be potentially very useful for making dialogs without too many GUI's...

Mat

Edited by Mat

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

$pFunc = DllCallbackGetPtr($pFunc)

edit; And DllCallbackFree($tFunc)

Code similar to this can be found on the forum:

#NoTrayIcon
#include <WindowsConstants.au3>
#include <WinAPI.au3>

Opt("WinWaitDelay", 0)

Global $hGui = GUICreate("Test", 300, 300, 20, 100, -1, $WS_EX_TOPMOST)


Global $hButton_NonBlocking_InputBox = GUICtrlCreateButton("Show InputBox", 100, 100, 150, 25)
GUICtrlSetTip(-1, "Embedded binary or from resource")
Global $hButton_Classic_InputBox = GUICtrlCreateButton("Show classic InputBox", 100, 150, 150, 25)
GUICtrlSetTip(-1, "Classic. Everything blocked")

Global $hButton = GUICtrlCreateButton("FileOpenDialog", 20, 220, 120, 25) ; to see if blocked with dialogs. Shouldn't be for modeless versions.

;#cs
Global $bDialog = "0x0100FFFF00000000000004004C0ACC80040000000000A2005F00000000004100" & _
        "750074006F0049007400200049006E00700075007400200042006F0078000000" & _
        "0800000000014D00530020005300680065006C006C00200044006C0067000000" & _
        "0000000000000000000002500700070093002C00EA030000FFFF820050007200" & _
        "6F006D0070007400000000000000000000000000800081500700380093000C00" & _
        "E9030000FFFF8100000000000000000000000000010001501000490032000E00" & _
        "01000000FFFF80004F004B000000000000000000000000000000015057004900" & _
        "32000E0002000000FFFF8000430061006E00630065006C0000000000"

Global $tDialog = DllStructCreate("byte[" & BinaryLen($bDialog) & "]")
DllStructSetData($tDialog, 1, $bDialog)

Global $hDialogProc = DllCallbackRegister("_DialogProc", "int_ptr", "hwnd;dword;wparam;lparam")

;#cs
; Version with binary
Global $aCall = DllCall("user32.dll", "hwnd", "CreateDialogIndirectParamW", _
        "handle", 0, _
        "ptr", DllStructGetPtr($tDialog), _
        "hwnd", $hGui, _
        "ptr", DllCallbackGetPtr($hDialogProc), _
        "lparam", 0)

Global $hDialog = $aCall[0]
;#ce

#cs
    ; Version with resource
    Global $aCall = DllCall("user32.dll", "hwnd", "CreateDialogParamW", _
    "handle", 0, _
    "int", 1000, _ ; "int" because the name is number (IS_INTRESOURCE)
    "hwnd", $hGui, _
    "ptr", DllCallbackGetPtr($hDialogProc), _
    "lparam", 0)
    Global $hDialog = $aCall[0]
#ce

GUISetState()


While 1
    Switch GUIGetMsg()
        Case -3
            ExitLoop
        Case $hButton_NonBlocking_InputBox
            WinSetState($hDialog, 0, @SW_SHOW)
            ;_WinAPI_ShowWindow($hDialog)
        Case $hButton_Classic_InputBox
            InputBox("", "")
        Case $hButton
            FileOpenDialog("", "", "(*)", Default, "", $hGui)
    EndSwitch
WEnd

DllCall("user32.dll", "int", "DestroyWindow", "hwnd", $hDialog)
DllCallbackFree($hDialogProc) ; redundant


Func _DialogProc($hWnd, $iMsg, $wParam, $lParam)
    Switch $iMsg
        Case $WM_CLOSE
            WinSetState($hWnd, 0, @SW_HIDE); use DestroyWindow to destroy it (modeless dialog box)
        Case $WM_COMMAND
            Switch BitAND($wParam, 65535)
                Case 1
                    ConsoleWrite("'OK' clicked" & @CRLF)
                Case 2
                    ConsoleWrite("'Cancel'-ed" & @CRLF)
            EndSwitch
    EndSwitch
EndFunc   ;==>_DialogProc
Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

$pFunc = DllCallbackGetPtr($pFunc)

Kk... So thats bad. But it's not the problem unfortunately :mellow:

As said, there is an error with the resource itself.

Share this post


Link to post
Share on other sites

Kk... So thats bad. But it's not the problem unfortunately :mellow:

As said, there is an error with the resource itself.

I pointed to another issue (releasing callback) with your code in the edit.

And added working example. Actually reposted the old one.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

I pointed to another issue (releasing callback) with your code in the edit.

And added working example. Actually reposted the old one.

Great thanks... Thats better than I imagined. The only thing I don't get is where the binary comes from??

I didn't see that from searching because I was searching for DialogBox* rather than CreateDialog* :mellow:

Share this post


Link to post
Share on other sites

Great thanks... Thats better than I imagined. The only thing I don't get is where the binary comes from??

There are more than one way of getting binary. One would be to compile (PE) with that resource included. Then just read raw binary data of it.

Another and extremely cool way would be to parse res file (your Replace.txt) yourself. Link to all you would need in that case. That's how it should be done and that's how a decent programmer would do it.


♡♡♡

.

eMyvnE

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
Sign in to follow this  
Followers 0