2012-06-27 66 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... 

看看是否有幫助?

最佳, 弗蘭克