.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib ; calls to functions in user32.lib and kernel32.lib
include kernel32.inc
includelib kernel32.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
WndProc proto hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
PopulateWndClassEx proto wcAdr:DWORD,lpfnWndProc:DWORD,hInst:HANDLE,clsName:DWORD
.DATA ; initialized data
ClassName db "SimpleWinClass",0 ; the name of our window class
AppName db "Our First Window",0 ; the name of our window
.DATA? ; Uninitialized data
hInstance HINSTANCE ? ; Instance handle of our program
CommandLine LPSTR ?
.CODE ; Here begins our code
PopulateWndClassEx proc wcAdr:DWORD,lpfnwndproc:DWORD,hInst:HANDLE,clsName:DWORD
push eax
push ebx
push ecx
mov ebx,wcAdr
mov (WNDCLASSEX PTR ).cbSize, SIZEOF WNDCLASSEX
mov (WNDCLASSEX PTR ).style, CS_HREDRAW or CS_VREDRAW
mov ecx,lpfnwndproc
mov (WNDCLASSEX PTR ).lpfnWndProc,ecx
mov (WNDCLASSEX PTR ).cbClsExtra,NULL
mov (WNDCLASSEX PTR ).cbWndExtra,NULL
mov ecx,hInst
mov (WNDCLASSEX PTR ).hInstance,ecx
mov (WNDCLASSEX PTR ).hbrBackground,COLOR_WINDOW+1
mov (WNDCLASSEX PTR ).lpszMenuName,NULL
mov ecx,clsName
mov (WNDCLASSEX PTR ).lpszClassName,ecx
invoke LoadIcon,NULL,IDI_APPLICATION
mov (WNDCLASSEX PTR ).hIcon,eax
mov (WNDCLASSEX PTR ).hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov (WNDCLASSEX PTR ).hCursor,eax
pop ecx
pop ebx
pop eax
ret
PopulateWndClassEx EndP
start:
invoke GetModuleHandle, NULL ; get the instance handle of our program.
; Under Win32, hmodule==hinstance mov hInstance,eax
mov hInstance,eax
invoke GetCommandLine ; get the command line. You don't have to call this function IF
; your program doesn't process the command line.
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT ; call the main function
invoke ExitProcess, eax ; quit our program. The exit code is returned in eax from WinMain.
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX ; create local variables on stack
LOCAL msg:MSG
LOCAL hwnd:HWND
; invoke PopulateWndClassEx,addr wc,OFFSET WndProc,hInstance,OFFSET ClassName
;//BEGIN (normal) alternative block to the invoke above
mov wc.cbSize,SIZEOF WNDCLASSEX ; fill values in members of wc
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
;//END alternative (normal) execution block
invoke RegisterClassEx, addr wc ; register our window class
invoke CreateWindowEx,NULL,\
ADDR ClassName,\
ADDR AppName,\
WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
NULL,\
NULL,\
hInst,\
NULL
mov hwnd,eax
invoke ShowWindow, hwnd,CmdShow ; display our window on desktop
invoke UpdateWindow, hwnd ; refresh the client area
.WHILE TRUE ; Enter message loop
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam ; return exit code in eax
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY ; if the user closes our window
invoke PostQuitMessage,NULL ; quit our application
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; Default message processing
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
What I want is PopulateWndClassEx populate the structure found at wcAddr (partially hard-coded properties, but also via parameters supplied). The code won't work with "invoke PopulateWndClassEx ...", but why ? For simplification, some pseudocode using C syntax:
void PopulateWndClassEx(WNDCLASSEX* wcAddr,HANDLE hInst,<...>) {
/* What I have to do is dereferencing the pointer *wcAddr:*/
(*wcAddr).style = <...> /*and give values to the members of the struct*/
}
The asm code for PopulateWndClassEx has been written after reading http://www.hep.wisc.edu/~pinghc/asm5.html
code fixed, there were some typos (my fault). here is it, as somebody may find it useful:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib ; calls to functions in user32.lib and kernel32.lib
include kernel32.inc
includelib kernel32.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
WndProc proto hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
PopulateWndClassEx proto wcAdr:DWORD,lpfnWndProc:DWORD,hInst:HANDLE,clsName:DWORD
.DATA ; initialized data
ClassName db "SimpleWinClass",0 ; the name of our window class
AppName db "Our First Window",0 ; the name of our window
.DATA? ; Uninitialized data
hInstance HINSTANCE ? ; Instance handle of our program
CommandLine LPSTR ?
.CODE ; Here begins our code
PopulateWndClassEx proc wcAdr:DWORD,lpfnwndproc:DWORD,hInst:HANDLE,clsName:DWORD
mov ebx,wcAdr
mov (WNDCLASSEX PTR ).cbSize, SIZEOF WNDCLASSEX
mov (WNDCLASSEX PTR ).style, CS_HREDRAW or CS_VREDRAW
mov ecx,lpfnwndproc
mov (WNDCLASSEX PTR ).lpfnWndProc,ecx
mov (WNDCLASSEX PTR ).cbClsExtra,NULL
mov (WNDCLASSEX PTR ).cbWndExtra,NULL
mov ecx,hInst
mov (WNDCLASSEX PTR ).hInstance,ecx
mov (WNDCLASSEX PTR ).hbrBackground,COLOR_WINDOW+1
mov (WNDCLASSEX PTR ).lpszMenuName,NULL
mov ecx,clsName
mov (WNDCLASSEX PTR ).lpszClassName,ecx
invoke LoadIcon,NULL,IDI_APPLICATION
mov (WNDCLASSEX PTR ).hIcon,eax
mov (WNDCLASSEX PTR ).hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov (WNDCLASSEX PTR ).hCursor,eax
ret
PopulateWndClassEx EndP
;or alternative to it:
PopulateWndClassExAssume proc wcAdr:DWORD,lpfnwndproc:DWORD,hInst:HANDLE,clsName:DWORD
ASSUME ebx:PTR WNDCLASSEX
mov ebx,wcAdr
mov .cbSize, SIZEOF WNDCLASSEX
mov .style, CS_HREDRAW or CS_VREDRAW
mov ecx,lpfnwndproc
mov .lpfnWndProc,ecx
mov .cbClsExtra,NULL
mov .cbWndExtra,NULL
mov ecx,hInst
mov .hInstance,ecx
mov .hbrBackground,COLOR_WINDOW+1
mov .lpszMenuName,NULL
mov ecx,clsName
mov .lpszClassName,ecx
invoke LoadIcon,NULL,IDI_APPLICATION
mov .hIcon,eax
mov .hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov .hCursor,eax
ASSUME ebx:nothing
ret
PopulateWndClassExAssume EndP
start:
invoke GetModuleHandle, NULL ; get the instance handle of our program.
; Under Win32, hmodule==hinstance mov hInstance,eax
mov hInstance,eax
invoke GetCommandLine ; get the command line. You don't have to call this function IF
; your program doesn't process the command line.
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT ; call the main function
invoke ExitProcess, eax ; quit our program. The exit code is returned in eax from WinMain.
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX ; create local variables on stack
LOCAL msg:MSG
LOCAL hwnd:HWND
invoke PopulateWndClassEx,addr wc,OFFSET WndProc,hInstance,OFFSET ClassName
invoke RegisterClassEx, addr wc ; register our window class
invoke CreateWindowEx,NULL,\
ADDR ClassName,\
ADDR AppName,\
WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
CW_USEDEFAULT,\
NULL,\
NULL,\
hInst,\
NULL
mov hwnd,eax
invoke ShowWindow, hwnd,CmdShow ; display our window on desktop
invoke UpdateWindow, hwnd ; refresh the client area
.WHILE TRUE ; Enter message loop
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam ; return exit code in eax
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY ; if the user closes our window
invoke PostQuitMessage,NULL ; quit our application
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; Default message processing
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start