不知何故,如果不更改代码,我就无法再创建窗口了

问题描述 投票:0回答:1

我尝试在汇编中编写 pong 以更好地了解我的电脑中实际发生的情况

我已经禁用了我的AV,这会将其标记为有害,并在禁用AV的情况下重新启动我的电脑,并且代码之前可以工作,我没有更改任何内容。它可能是由于一些愚蠢的疏忽,但作为一个通常的高级程序员,代码在重新启动我的电脑后就停止工作,这真的很奇怪。我没有收到任何有关的错误。

我明白了

hello.asm(51):警告 A6001:过程没有返回

这是一个错误,但我之前可以忽略它,它会编译,就像我之前说的那样。

.386
.model flat, stdcall
option casemap:none

include C:\MASM32\include\masm32rt.inc
includelib user32.lib
includelib kernel32.lib

.data
    txClass db "MyWinClass", 0
    wcx     WNDCLASSEX <WNDCLASSEX, CS_HREDRAW or CS_VREDRAW, WndProc, 0, 0, 1, 2, 3, COLOR_BTNFACE+1, 0, txClass, 4>
    rect    RECT <20, 0, 40, 100> ; Rectangle to hold the client area dimensions
    ball    RECT <200, 200, 210,210> ; Rectangle to hold the client area dimensions
    ballMX  DWORD 5
    ballMY  DWORD 5
.data? ; uninitialised data - use for handles etc
    hMenu   dd ?
    ps PAINTSTRUCT<?>
    dwStartTime DWORD ?
    dwElapsedTime DWORD ?
    hWnd2  DWORD ?
.code
WinMain proc uses ebx
    LOCAL msg:MSG

    
    
    mov ebx, offset wcx
    wc equ [ebx.WNDCLASSEX]
    mov wc.hInstance, rv(GetModuleHandle, 0)
    mov wc.hIcon, rv(LoadIcon, NULL, IDI_APPLICATION)
    mov wc.hIconSm, eax

    invoke RegisterClassEx, addr wc
    invoke CreateWindowEx, NULL, wc.lpszClassName, chr$("Pong"),
        WS_OVERLAPPEDWINDOW or WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, wc.hInstance, NULL

    mov hWnd2, eax
    invoke SetTimer, hWnd2, 1, 8, NULL

    .While 1
        invoke GetMessage, ADDR msg, NULL, 0, 0
        .Break .if !eax
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .Endw
    
    exit msg.wParam
WinMain endp

WndProc proc uses esi edi ebx hWnd, uMsg, wParam:WPARAM, lParam:LPARAM
    LOCAL hdc: HDC

    
    SWITCH uMsg

    CASE WM_CREATE
    ret
    CASE WM_KEYDOWN
        mov eax, wParam
        SWITCH eax
        CASE VK_S
            add dword ptr [rect.top], 5
            add dword ptr [rect.bottom], 5
        CASE VK_W
            sub dword ptr [rect.top], 5
            sub dword ptr [rect.bottom], 5
            ret
    ret
    ENDSW
    invoke InvalidateRect, hWnd, NULL, TRUE ; Force the window to repaint
    ret 

    CASE WM_TIMER
        push ebx
        mov eax, ball.bottom
        mov ebx, ps.rcPaint.bottom
        cmp eax,ebx
        jb cont
        neg  ballMY
    cont:
        mov eax,ballMY
        add ball.top, eax     
        add ball.bottom, eax
        
        xor ebx, ebx
        
        mov eax, ball.right
        mov ebx, ps.rcPaint.right
        cmp eax,ebx
        jb cont2
        neg  ballMX
    cont2:
        mov eax,ballMX
        add ball.left, eax     
        add ball.right, eax    
        
        pop ebx
        
        
        
        
        invoke InvalidateRect, hWnd, NULL, TRUE  ; Request a repaint

    CASE WM_PAINT
    
        invoke BeginPaint, hWnd, ADDR ps ; Start painting the window
        mov hdc, eax                   ; Store the device context handle
        invoke CreateSolidBrush, 0000000
        invoke FillRect, hdc, ADDR ps.rcPaint, eax


        invoke CreateSolidBrush, 0FFFFFFh
        invoke FillRect, hdc, ADDR rect, eax
        
        
        invoke CreateSolidBrush, 0FFFFFFh
        invoke FillRect, hdc, ADDR ball, eax

        invoke EndPaint, hWnd, ADDR ps   ; End painting
        ret

    CASE WM_DESTROY
        invoke PostQuitMessage, NULL

    ENDSW
    invoke DefWindowProc, hWnd, uMsg, wParam, lParam
    ret
WndProc endp

end WinMain
winapi x86 masm
1个回答
0
投票

RegisterClassEx
失败了

invoke RegisterClassEx, addr wc

用新代码替换了原始代码,用所需变量填充 WNDCLASSEX 结构。

运行代码会产生此窗口

pong.asm

.386
.model flat, stdcall
option casemap:none

include C:\MASM32\include\masm32rt.inc
includelib user32.lib
includelib kernel32.lib

.data
    txClass db "MyWinClass", 0
    rect    RECT <20, 0, 40, 100> ; Rectangle to hold the client area dimensions
    ball    RECT <200, 200, 210,210> ; Rectangle to hold the client area dimensions
    ballMX  DWORD 5
    ballMY  DWORD 5
.data? ; uninitialised data - use for handles etc
    hMenu   dd ?
    ps PAINTSTRUCT<?>
    dwStartTime DWORD ?
    dwElapsedTime DWORD ?
    hWnd2  DWORD ?


.code
WinMain proc hInst     :DWORD,
             hPrevInst :DWORD,
             CmdLine   :DWORD,
             CmdShow   :DWORD   
    
        ;====================
        ; Put LOCALs on stack
        ;====================

        LOCAL wc   :WNDCLASSEX
        LOCAL msg  :MSG

        LOCAL Wwd  :DWORD
        LOCAL Wht  :DWORD
        LOCAL Wtx  :DWORD
        LOCAL Wty  :DWORD

        ;==================================================
        ; Fill WNDCLASSEX structure with required variables
        ;==================================================

        mov wc.cbSize,         sizeof WNDCLASSEX
        mov wc.style,          CS_HREDRAW or CS_VREDRAW \
                               or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc,    offset WndProc
        mov wc.cbClsExtra,     NULL
        mov wc.cbWndExtra,     NULL
        m2m wc.hInstance,      hInst   ;<< NOTE: macro not mnemonic
        mov wc.hbrBackground,  COLOR_BTNFACE+1
        mov wc.lpszMenuName,   NULL
        mov wc.lpszClassName,  offset txClass
        invoke LoadIcon,hInst,500    ; icon ID
        mov wc.hIcon,          eax
        invoke LoadCursor,NULL,IDC_ARROW
        mov wc.hCursor,        eax
        mov wc.hIconSm,        0

        invoke RegisterClassEx, ADDR wc
        test eax, eax
        jnz regOk

        invoke MessageBox,0,SADD("RegistrationFailed"),
                            SADD("Oops"),
                            MB_OK or MB_ICONINFORMATION
        jmp done
                                 
regOk:
    invoke CreateWindowEx, NULL, wc.lpszClassName, chr$("Pong"),
        WS_OVERLAPPEDWINDOW or WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, wc.hInstance, NULL

    mov hWnd2, eax
    invoke ShowWindow,hWnd2,SW_SHOWNORMAL
    invoke UpdateWindow,hWnd2

    invoke SetTimer, hWnd2, 1, 8, NULL

    .While 1
        invoke GetMessage, ADDR msg, NULL, 0, 0
        .Break .if !eax
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .Endw

done:
    exit msg.wParam
WinMain endp

WndProc proc uses esi edi ebx hWnd, uMsg, wParam:WPARAM, lParam:LPARAM
    LOCAL hdc: HDC

    
    SWITCH uMsg

    CASE WM_CREATE
    ret
    CASE WM_KEYDOWN
        mov eax, wParam
        SWITCH eax
        CASE VK_S
            add dword ptr [rect.top], 5
            add dword ptr [rect.bottom], 5
        CASE VK_W
            sub dword ptr [rect.top], 5
            sub dword ptr [rect.bottom], 5
            ret
    ret
    ENDSW
    invoke InvalidateRect, hWnd, NULL, TRUE ; Force the window to repaint
    ret 

    CASE WM_TIMER
        push ebx
        mov eax, ball.bottom
        mov ebx, ps.rcPaint.bottom
        cmp eax,ebx
        jb cont
        neg  ballMY
    cont:
        mov eax,ballMY
        add ball.top, eax     
        add ball.bottom, eax
        
        xor ebx, ebx
        
        mov eax, ball.right
        mov ebx, ps.rcPaint.right
        cmp eax,ebx
        jb cont2
        neg  ballMX
    cont2:
        mov eax,ballMX
        add ball.left, eax     
        add ball.right, eax    
        
        pop ebx
        
        
        
        
        invoke InvalidateRect, hWnd, NULL, TRUE  ; Request a repaint

    CASE WM_PAINT
    
        invoke BeginPaint, hWnd, ADDR ps ; Start painting the window
        mov hdc, eax                   ; Store the device context handle
        invoke CreateSolidBrush, 0000000
        invoke FillRect, hdc, ADDR ps.rcPaint, eax


        invoke CreateSolidBrush, 0FFFFFFh
        invoke FillRect, hdc, ADDR rect, eax
        
        
        invoke CreateSolidBrush, 0FFFFFFh
        invoke FillRect, hdc, ADDR ball, eax

        invoke EndPaint, hWnd, ADDR ps   ; End painting
        ret

    CASE WM_DESTROY
        invoke PostQuitMessage, NULL

    ENDSW
    invoke DefWindowProc, hWnd, uMsg, wParam, lParam
    ret
WndProc endp

end WinMain

C:\masm32\tools
C:\masm32\examples
中有很多示例使用此代码正确注册Windows类

RegisterWinClass proc lpWndProc:DWORD, lpClassName:DWORD,
                      Icon:DWORD, Cursor:DWORD, bColor:DWORD

    LOCAL wc:WNDCLASSEX

    mov wc.cbSize,         sizeof WNDCLASSEX
    mov wc.style,          CS_BYTEALIGNCLIENT or \
                           CS_BYTEALIGNWINDOW
    m2m wc.lpfnWndProc,    lpWndProc
    mov wc.cbClsExtra,     NULL
    mov wc.cbWndExtra,     NULL
    m2m wc.hInstance,      hInstance
    m2m wc.hbrBackground,  bColor
    mov wc.lpszMenuName,   NULL
    m2m wc.lpszClassName,  lpClassName
    m2m wc.hIcon,          Icon
    m2m wc.hCursor,        Cursor
    m2m wc.hIconSm,        Icon

    invoke RegisterClassEx, ADDR wc

    ret

RegisterWinClass endp
© www.soinside.com 2019 - 2024. All rights reserved.