Another version using structures to pass data to the thread creating the message box.
include MBox.inc
MBOX STRUCT
hWnd DWORD ?
msg DWORD ?
capt DWORD ?
MBOX ENDS
MDATA STRUCT
ThreadID DWORD ?
hWnd DWORD ?
MDATA ENDS
.data
capt db "Hello!",0
msg db 'Customized message box',0
msg2 db 'You clicked the Help button',0
ButtonText db 'Click here',0
bclass db 'Button',0
.data?
pOldProc dd ?
HelpBtnID dd ?
.code
start:
invoke CustMsgBox,0,ADDR msg,ADDR capt,ADDR ButtonText
invoke ExitProcess,0
CustMsgBox PROC uses esi handle:DWORD,message:DWORD,caption:DWORD,button:DWORD
LOCAL ThreadID:DWORD
LOCAL hThread:DWORD
LOCAL hClick:DWORD
LOCAL mboxparam:MBOX
LOCAL mboxdata:MDATA
lea edx,mboxparam
push handle
pop MBOX.hWnd[edx]
push message
pop MBOX.msg[edx]
push caption
pop MBOX.capt[edx]
invoke CreateThread,0,0,ADDR ThreadProc,\
edx,0,ADDR ThreadID
mov hThread,eax
invoke GetCurrentProcess
invoke WaitForInputIdle,eax,INFINITE
lea esi,mboxdata
push ThreadID
pop MDATA.ThreadID[esi]
invoke EnumWindows,ADDR EnumWndProc,\
esi
invoke FindWindowEx,MDATA.hWnd[esi],\
0,ADDR bclass,0
mov hClick,eax
invoke FindWindowEx,MDATA.hWnd[esi],\
eax,ADDR bclass,0
invoke GetDlgCtrlID,eax
mov HelpBtnID,eax
invoke SetWindowText,hClick,button
invoke SetWindowLong,MDATA.hWnd[esi],GWL_WNDPROC,\
ADDR MsgboxProc
mov pOldProc,eax
invoke WaitForSingleObject,hThread,INFINITE
invoke CloseHandle,hThread
ret
CustMsgBox ENDP
ThreadProc PROC pParams:DWORD
mov edx,pParams
invoke MessageBox,MBOX.hWnd[edx],\
MBOX.msg[edx],MBOX.capt[edx],\
MB_HELP
ret
ThreadProc ENDP
EnumWndProc PROC hWnd:DWORD,lParam:DWORD
LOCAL pid:DWORD
invoke GetWindowThreadProcessId,hWnd,ADDR pid
mov edx,lParam
cmp eax,MDATA.ThreadID[edx]
jne @f
push hWnd
pop MDATA.hWnd[edx] ; get the handle of the window
xor eax,eax ; displaying the message box
ret
@@:
mov eax,TRUE
ret
EnumWndProc ENDP
MsgboxProc PROC hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.IF uMsg == WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
.IF dx==BN_CLICKED
mov ecx,HelpBtnID
.IF ax==cx
invoke MessageBox,0,ADDR msg2,ADDR capt,MB_OK
.ENDIF
.ENDIF
.ENDIF
invoke CallWindowProc,pOldProc,hWnd,uMsg,wParam,lParam
ret
MsgboxProc ENDP
END start