Hello, this is a message dispatcher system written in MASM macro.

It automatically builds a table for a window class, provides a dispatcher for that class to load into a window class's lpfnWndProc, and can support superclassing, subclassing, and dialog boxes as well as ordinary window procs.

Hope you like it, here is a sample of code written for it:


TITLE Dispatch System test program.

.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE


include evrythng.inc
include dispatch.inc
;include \masm32\include\debug.inc
;includelib \masm32\lib\debug.lib

IDM_TEST EQU 1
IDM_HELLO EQU 2
IDM_GOODBYE EQU 3
IDM_EXIT EQU 4

IDC_EDIT EQU 3000
IDC_BUTTON EQU 3001
IDC_EXIT EQU 3002


;=================
; Local prototypes
;=================
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD

;These are the dispatchers created by dispatch.inc
TestDialogWindowProc PROTO
MainWindowProc PROTO

;These are the message processors we defined for the 'Main' window class
MainWM_DESTROYWindowProc ProtoWindowProc
MainWM_PAINTWindowProc ProtoWindowProc
MainWM_LBUTTONDOWNWindowProc ProtoWindowProc
MainWM_CHARWindowProc ProtoWindowProc
MainWM_COMMANDWindowProc ProtoWindowProc

;the following lines causes WM_RBUTTONDOWN messages to be sent to
;MainWM_LBUTTONDOWNWindowProc
MainWM_RBUTTONDOWNWindowProc textequ <MainWM_LBUTTONDOWNWindowProc>

;These are the message processors we defined for the 'TestDialog' window class
TestDialogWM_INITDIALOGWindowProc ProtoWindowProc
TestDialogWM_CLOSEWindowProc ProtoWindowProc
TestDialogWM_COMMANDWindowProc ProtoWindowProc


.DATA
CommandLine dd 0
hWndMain dd 0
hInstance dd 0
hIcon dd 0
AppName db "Test Program",0
MainWndClass db "TestWindowClass",0
TestMenu db "TestMenu",0
TestDialogTemplate db "TestDialog",0
char WPARAM 20h

.data?
MouseLocation dd ?,?
MouseClicked dd ?

.data
;Window Class Registration structure(s)
wcMain WNDCLASSEX\
<sizeof WNDCLASSEX,\
CS_HREDRAW or CS_VREDRAW,\
MainWindowProc,\
NULL,\
NULL,\
NULL,\
NULL,\
NULL,\
COLOR_WINDOW + 1,\
TestMenu,\
MainWndClass,\
NULL>

.data
TestString db "Hello Cruel World! I'm in an edit box now!",0
HelloString db "Hello World!",0
GoodbyeString db "Goodbye Carlo!",0

.CODE
DefDialogBoxProc proc
xor eax,eax
ret 10h
DefDialogBoxProc endp


start:
;Initialization section
Invoke GetModuleHandle, NULL
mov hInstance,eax
Invoke GetCommandLine
mov CommandLine,eax

;Initializators for the 'Main' and 'TestDialog' dispatchers
;required for compatibility with ddspatch.inc
InitializatorFor Main
InitializatorFor TestDialog,DialogBox

;WinMain section
Invoke WinMain, hInstance,NULL,CommandLine,SW_SHOWDEFAULT

;ShutDown section
Invoke ExitProcess, eax

;WinMain - Main procedure of the program
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL msg:MSG
;Window Class Registration section
;-----------------------wcMain
;Load uninitialized data
mov eax,hInst
mov wcMain.hInstance,eax
Invoke LoadIcon, NULL,IDI_APPLICATION
mov wcMain.hIcon,eax
mov wcMain.hIconSm,eax
Invoke LoadCursor, NULL,IDC_ARROW
mov wcMain.hCursor,eax
Invoke RegisterClassEx, addr wcMain

;application init section
mov MouseClicked,FALSE

;Window Creation section
; CreateWindowEx, NULL, Window Class Name, Window Title,\
; Window Type,\
; x,y,\
; cx,cy,\
; Parent, Menu, Instance, Parameters
;-----------------------Create Main Window
Invoke CreateWindowEx, NULL,addr MainWndClass,addr AppName,\
WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,\
NULL,NULL,hInst,NULL
mov hWndMain,eax

Invoke ShowWindow, hWndMain,SW_SHOWNORMAL
Invoke UpdateWindow, hWndMain

;Message Loop section
MessageLoopBegins:
Invoke GetMessage, addr msg,NULL,0,0
cmp eax,0
jz MessageLoopEnds
Invoke TranslateMessage, addr msg
Invoke DispatchMessage, addr msg
jmp MessageLoopBegins
MessageLoopEnds:

;Closing Section

;fin
Return msg.wParam
WinMain endp


;--------------------------------------------------------------------------Main
;'Main' Window Class WindowProc's
;------------------------------------------------------------------------------

DispatcherFor Main


MainWM_DESTROYWindowProc WindowProc
Invoke PostQuitMessage, NULL
Return 0
MainWM_DESTROYWindowProc endp


MainWM_PAINTWindowProc WindowProc
LOCAL hDC:HDC
LOCAL ps:PAINTSTRUCT
LOCAL ClientRect:RECT

Invoke BeginPaint, hWnd,addr ps
mov hDC,eax
Invoke GetClientRect, hWnd,addr ClientRect

;-----------Meat of the Paint Procedure HERE!
cmp MouseClicked,TRUE
jne notMouseClicked
szText text,"Mouse was clicked here..."
Invoke TextOut, hDC,MouseLocation,MouseLocation[4],addr text,25
notMouseClicked:
Invoke TextOut, hDC,0,0,addr char,1

Invoke EndPaint, hWnd,addr ps
xor eax,eax
ret
MainWM_PAINTWindowProc endp

MainWM_LBUTTONDOWNWindowProc WindowProc
mov MouseClicked,TRUE
movsx eax,word ptr lParam
movsx ebx,word ptr lParam[2]
mov MouseLocation,eax
mov MouseLocation[4],ebx
Invoke InvalidateRect, hWnd,NULL,TRUE
xor eax,eax
ret
MainWM_LBUTTONDOWNWindowProc endp

MainWM_CHARWindowProc WindowProc
push wParam
pop char
Invoke InvalidateRect, hWnd,NULL,TRUE
xor eax,eax
ret
MainWM_CHARWindowProc endp

MainWM_COMMANDWindowProc WindowProc
movzx eax,word ptr wParam
cmp eax,IDM_TEST
jne EndIDM_TEST
StartIDM_TEST:
Invoke DialogBoxParam, hInstance,addr TestDialogTemplate,\
hWnd,offset TestDialogWindowProc,NULL
jmp getout
EndIDM_TEST:

cmp eax,IDM_HELLO
jne EndIDM_HELLO
StartIDM_HELLO:
Invoke MessageBox, NULL,addr HelloString,offset AppName,MB_OK
jmp getout
EndIDM_HELLO:

cmp eax,IDM_GOODBYE
jne EndIDM_GOODBYE
StartIDM_GOODBYE:
Invoke MessageBox, NULL,addr GoodbyeString,offset AppName,MB_OK
jmp getout
EndIDM_GOODBYE:

cmp eax,IDM_EXIT
jne EndIDM_EXIT
StartIDM_EXIT:
Invoke DestroyWindow, hWnd
EndIDM_EXIT:

getout:
xor eax,eax
ret
MainWM_COMMANDWindowProc endp


;--------------------------------------------------------------------TestDialog
;TestDialog's WindowProcs
;------------------------------------------------------------------------------


DispatcherFor TestDialog,DialogBox


TestDialogWM_INITDIALOGWindowProc WindowProc
Invoke GetDlgItem, hWnd,IDC_EDIT
Invoke SetFocus, eax
mov eax,TRUE
ret
TestDialogWM_INITDIALOGWindowProc endp


TestDialogWM_CLOSEWindowProc WindowProc
Invoke EndDialog, hWnd,NULL
mov eax,TRUE
ret
TestDialogWM_CLOSEWindowProc endp

TestDialogWM_COMMANDWindowProc WindowProc
movzx edx,word ptr wParam+2
movzx eax,word ptr wParam
cmp edx,BN_CLICKED
jne ignoreit
cmp eax,IDC_EXIT
jne notexit
Invoke SendMessage, hWnd,WM_CLOSE,NULL,NULL
jmp ignoreit
notexit:
cmp eax,IDC_BUTTON
jne ignoreit
Invoke SetDlgItemText, hWnd,IDC_EDIT,addr TestString
ignoreit:
mov eax,TRUE
ret
TestDialogWM_COMMANDWindowProc endp


end start



please read more about it in the documentation.
Posted on 2002-08-18 19:48:23 by AmkG
Hey, cool. :cool: :alright:

Very useful. Good job. ;)
Posted on 2002-08-18 19:56:34 by iblis
Gee, thanks.


BTW there are two versions of the dispatcher, one is dispatch.inc, the other is ddspatch.inc, dispatch.inc creates the dispatcher table at compile-time, ddspatch.inc creates the table at run-time. Dispatch.inc thus makes a larger exe file, but with no overhead, while ddspatch.inc makes a smaller exe file, but requires table-creation code at init (the 'InitializatorFor' macro).

Anyway the sample code above will work with either dispatch.inc or ddspatch.inc, you only need to change the include line.
Posted on 2002-08-18 20:17:59 by AmkG