2012-06-27 48 views
-1

我尝试使用程序集NASM创建最简单的WinAPI窗口。 我有Window Proc的问题。看看注释行:如何获取窗口proc参数?

 
%macro API 2 
    import %1 %2 
    extern %1 
%endmacro 

API GetModuleHandleA, kernel32.dll 
API LoadIconA,user32.dll 
API LoadCursorA,user32.dll 
API RegisterClassExA, user32.dll 
API CreateWindowExA, user32.dll 
API MessageBoxA, user32.dll 
API SendMessageA, user32.dll 
API DefWindowProcA, user32.dll 
API ExitProcess, kernel32.dll 
API GetMessageA, user32.dll 
API DispatchMessageA, user32.dll 
API TranslateMessage,user32.dll 
API ShowWindow,user32.dll 
API UpdateWindow,user32.dll 
API GetCommandLineA,kernel32.dll 
API PostQuitMessage,user32.dll 

segment .data USE32 
    windowName db "Hello world!", 0 
    cmdLine dd 0 
    hWnd  dd 0 
    hInst  dd 0 
    hCursor dd 0 
    className db "moje_okno",0 

    blad  db "Blad!!!",0 

segment .bss 
    struc WNDCLASSEX 
     .sSize   resb 4 
     .style   resb 4 
     .wndProc  resb 4 
     .clsExtra  resb 4 
     .wndExtra  resb 4 
     .hInstance  resb 4 
     .hIcon   resb 4 
     .hCursor  resb 4 
     .background resb 4 
     .sMenuName  resb 4 
     .sClassName resb 4 
     .hIconSm  resb 4 
    endstruc 

    wndClass istruc WNDCLASSEX 
    iend 

global ..start 
segment .text USE32 
..start: 
    push 0 
    call [GetModuleHandleA] 
    mov dword [hInst], eax ; application handle 

    push dword 0x00007f00 ; MAKEINTRESOURCE(32512) 
    push dword 0 
    call [LoadCursorA] 
    mov dword [hCursor], eax ; cursor handle 

    mov dword [wndClass + WNDCLASSEX.sSize],  dword 48 ; struct size 
    mov dword [wndClass + WNDCLASSEX.style],  dword 0 ; style 
    mov dword [wndClass + WNDCLASSEX.wndProc], wndproc ; window proc 
    mov dword [wndClass + WNDCLASSEX.clsExtra], dword 0 
    mov dword [wndClass + WNDCLASSEX.wndExtra], dword 0 
    mov eax, dword [hInst] 
    mov dword [wndClass + WNDCLASSEX.hInstance], eax ; handle 
    mov dword [wndClass + WNDCLASSEX.hIcon],  dword 0 
    mov eax, dword [hCursor] 
    mov dword [wndClass + WNDCLASSEX.hCursor], eax 
    mov dword [wndClass + WNDCLASSEX.background], dword 0 
    mov dword [wndClass + WNDCLASSEX.sMenuName], dword 0 
    mov dword [wndClass + WNDCLASSEX.sClassName], className ; class name 
    mov dword [wndClass + WNDCLASSEX.hIconSm], dword 0 

    push wndClass 
    call [RegisterClassExA] 
    call near sprawdz_blad ; check return value of RegisterClassExA 

    push 0 ; param 
    push dword [hInst] ; handle 
    push 0 ;hMenu 
    push 0 ;parent 
    push 200 ;height 
    push 200 ;width 
    push 200 ;y 
    push 200 ;x 
    push 0 ;style 
    push className ;window name 
    push className ;window class 
    push 0 ;extended style 
    call [CreateWindowExA] 
    push eax 
    call near sprawdz_blad ;check return value of CreateWindowExA. RETURNS 0 

    push 0 
    call [ExitProcess] 

wndproc: 
    ; HERE I NEED ACCESS TO WINDOW PROC PARAMETERS: HWND, MSG, WPARAM, LPARAM 
    ; I TRIED: 
    pop eax 
    pop ebx 
    pop ecx 
    pop edx 
    ; BUT IT DOESN'T WORK 
    ; THERE ARE NOT RIGHT VALUES IN THESE REGISTRIES 


    ret 

box: 
    push 0 
    push blad 
    push blad 
    push 0 
    call [MessageBoxA] 
    ret 

sprawdz_blad: 
    pop eax 
    cmp eax, 0 
    jne ok ; if function returns 0 everything is allright 

    push 0 
    push blad 
    push blad 
    push 0 
    call [MessageBoxA] 

    push 1 
    call [ExitProcess] 
ok: 
    ret 


我试图让它工作几个小时,但我没有想法。 请帮忙。 迈克尔的问候。

+0

请告诉我不工作?发生了什么,什么不会发生? – eandersson

+0

在调用CreateWindow之后,系统会调用wndproc。直到它不返回DefWindowProc,CreateWindow返回0.但是为了调用DefWindowProc我需要访问wndproc参数。 – micnyk

回答

2

一个被调用的子例程,无论你自己调用它还是被Windows调用(如wndproc),它的返回地址都是堆栈中的第一个东西。你不想弹出这个!要访问这些参数,您需要看看堆栈的更远处。试着像...

wndproc: 
    mov eax, [esp + 4] 
    mov ebx, [esp + 8] 
; etc... 

看看是否有帮助?

最佳, 弗兰克