Pelles C forum
Assembly language => Assembly discussions => Topic started by: Vortex on January 29, 2012, 05:26:31 PM
-
Attached is an example of a customized message box.
-
Very nice!
-
Hi Vortex... forgive my naivety on ASM... but wouldn't it be easier to just make a dialog box?
-
Nice, now you can C it ;)
-
Hi CommonTater,
As you said, it's always much more easy to create a dialog box. My example is just a coding exercise as there is no any direct method \ API call to modify message boxes.
Here is an article based on Windows hooks :
Custom MessageBox (http://catch22.net/tuts/custom-messagebox)
My approach is to move the message box creation to a separate thread.
Hi timovjl,
Thanks for the C code.
-
Hi CommonTater,
As you said, it's always much more easy to create a dialog box. My example is just a coding exercise as there is no any direct method \ API call to modify message boxes.
Ahhh... Now I see. Actually it's a pretty clever trick....
I knew you'd know how to make dialog boxes, that's why I wondered what the point was.
-
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