.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
Posted on 2006-11-18 05:18:11 by bhavacakra
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
Posted on 2006-11-18 09:07:46 by bhavacakra