Is it posible to display a dialog box from within a DLL? I've been
trying to a call a function inside the dll which would then display
the dialog but no success... Can anyone give me an idea?
Below I have included the most important parts. I know that the dll
is loading and calling the function because the GetLastError reports
Error 87 = ERROR_INVALID_PARAMETER. Any pointers on a fix would be
greatly appreciated!

---------Main Program Code---------

; Test our RAMiscC.DLL...
invoke LoadLibrary, addr TestDLL
mov hLib, eax

invoke GetProcAddress, hLib, addr MSGTestFunc

; Pass test arg...
mov edx, addr ProgramName
push edx

; Call our Test DLL function...
call eax

invoke FreeLibrary, hLib

------------DLL CODE---------------
DLLName db "test.dll", 0
ErrorMessageCode db "%i", 0

hInstance dd ?

IDD_MSGDLG equ 101

. DLL Attach stuff
; Display dialog box
invoke DialogBoxParam, hInstance, IDD_MSGDLG, NULL, addr MSGBOXProc, NULL

; For some reason it aint workin so display the damn error :(
invoke GetLastError
invoke wsprintf, addr ErrorBuffer, addr ErrorMessageCode, eax
invoke MessageBox, NULL, addr ErrorBuffer, addr DLLName, MB_OK


; MSGBOXProc - This is a test dialog
MSGBOXProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
invoke MessageBox, NULL, addr MSGBOXFunc, addr DLLName, MB_OK

.elseif uMsg == WM_CLOSE
invoke EndDialog, hWnd, NULL

.elseif uMsg == WM_COMMAND
mov eax, wParam

.if lParam == 0
mov edx, wParam
shr edx, 16
invoke EndDialog, hWnd, NULL
mov eax, FALSE


mov eax, TRUE
MSGBOXProc endp

Thanks again,
Posted on 2002-02-01 11:54:38 by JamesE
If the dialog resource is in the DLL, then the hInstance you pass to DialogBoxParam must be the hInstance of the DLL, which I believe is hLib in your case.
Posted on 2002-02-01 15:57:55 by tank

tank is right. Best is to save the module handle in dll startup code. Looks like:

DllMain PROC public Inst:HINSTANCE,dwReason:dword,lpReserved:dword

mov eax,hInst
mov hInstance,eax

Another point which might cause problems:

a dialog proc should return zero if it doesn't process a message. Yours always returns TRUE.

Posted on 2002-02-01 17:40:09 by japheth
Hey tank,

Thanks for the reply, below is the entry point to the dll... I'm pretty sure the code is correct but I'm sorta new to dlls and assembler so... anyways here it is:

; LibMain - Entry Point to the dll
LibMain proc hInst:DWORD, reason:DWORD, unused:DWORD
push hInst
pop hInstance

.if reason == DLL_PROCESS_ATTACH
; Return TRUE so windows knows everything is ok!
mov eax, TRUE

.elseif reason == DLL_PROCESS_DETACH
invoke MessageBox, NULL, addr DetachDLL, addr DLLName, MB_OK

.elseif reason == DLL_THREAD_ATTACH
invoke MessageBox, NULL, addr ThreadAttach, addr DLLName, MB_OK

.elseif reason == DLL_THREAD_DETACH
invoke MessageBox, NULL, addr ThreadDetach, addr DLLName, MB_OK



LibMain endp

I'm sure I'll figure it out... It must be something really small and pretty obvious like many of the bugs you run into everyday.

Thanks for the reply!
Posted on 2002-02-01 17:41:06 by JamesE

The info you have been given here is correct, make sure you use the INSTANCE handle that is passed to the LibMain/DllMain for the dialog if you use resources in the DLL.

Usually you make a GLOBAL value in the .DATA? section,

hInstance dd ?

Somewhere in the LibMain DLL_PROCESS_ATTACH you copy the instance handle to the global variable,

mov eax, hInst
mov hInstance, eax ; << handle is now global

(Your push/pop works fine on the global as well)

and then when you call the dialog box from a function in the DLL, you use the DLLs instance handle that you have saved to the global variable.

This should get you out of trouble. Just make sure you use the correct ID for the dialog and get the handles for any controls you choose to use.

Posted on 2002-02-01 20:23:21 by hutch--