99101553@qq.com 发表于 2016-8-27 11:19:11

Win32 汇编例程问题?

例程源码:编译成功,发现一个问题就是 在关闭的时候,主进程没有结束。用W32Dasm反汇编检查了,好像没有问题。但实在想不出是哪个地方出了问题,好像是在call _WinMain之后没有返回调用 invoke ExitProcess,NULL导致,但_WinMain进程结束前都没有少ret 返回。

请鱼油们帮忙想下是哪里出了问题


;************first window**************
;copyright by yang 20160821
;======================================

        .386
        .model flat,stdcall
        option casemap:none

include                windows.inc
include                 gdi32.inc
includelib         gdi32.lib
include                 user32.inc
includelib        user32.lib
include                kernel32.inc
includelib        kernel32.lib


        .data?
hInstance                dd ?
hWinMain                dd ?
       
        .const
szClassName                db 'MyClass',0
szCaptionMain        db 'MyWindow',0
szText                        db 'This is my first Window!',0
       
       
        .code
;**************************************************
;窗口过程消息处理
;**************************************************       
_ProcWinMain        proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
                                local        @stPs:PAINTSTRUCT   
                                local        @stRect:RECT
                                local        @hDc:HDC
                               
                                mov         eax,uMsg
                               
                                .if                eax == WM_PAINT
                                                invoke        BeginPaint,hWnd,addr @stPs
                                                mov                @hDc,eax
                                               
                                                invoke        GetClientRect,hWnd,addr @stRect
                                                invoke        DrawText, @hDc , addr szText,-1,\
                                                                addr @stRect,\
                                                                DT_SINGLELINE or DT_CENTER or DT_VCENTER
                                                invoke        EndPaint,hWnd,addr @stPs
                                .elseif        eax ==WM_CLOSE
                                                invoke        DestroyWindow,hWinMain
                                                invoke        PostQuitMessage,NULL
                                .else
                                                invoke        DefWindowProc,hWnd,uMsg,wParam,lParam
                                                ret
                                .endif
                                xor         eax,eax
                                ret
_ProcWinMain endp

;*************************************************
;_WinMain proc
;*************************************************
_WinMain        proc
                        local        @stWndClass:WNDCLASSEX
                        local        @stMsg:MSG
                       
                        invoke        GetModuleHandle,NULL
                        mov                hInstance,eax
                       
                        invoke        RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;*************************************************
;注册窗口类
;*************************************************
                        invoke        LoadCursor,0,IDC_ARROW
                        mov                @stWndClass.hCursor,eax
                        push        hInstance
                        pop                @stWndClass.hInstance
                        mov                @stWndClass.cbSize,sizeof WNDCLASSEX
                        mov         @stWndClass.style,CS_HREDRAW or CS_VREDRAW
                        mov         @stWndClass.hbrBackground,COLOR_WINDOW+1
                        mov         @stWndClass.lpszClassName,offset szClassName
                        mov         @stWndClass.lpfnWndProc,offset _ProcWinMain ;
                        invoke        RegisterClassEx,addr @stWndClass
;****************************************************
;建立窗口,显示窗口
;****************************************************
                        invoke        CreateWindowEx,WS_EX_CLIENTEDGE ,\
                                        offset szClassName,offset szCaptionMain,\
                                        WS_TILEDWINDOW,0,0,300,200,NULL,NULL,hInstance,NULL
                        mov                hWinMain,eax
                        invoke        ShowWindow,hWinMain,SW_SHOWNORMAL
                        invoke        UpdateWindow,hWinMain
;*****************************************************
;消息循环
;*****************************************************
                        .while TRUE
                                        invoke         GetMessage,addr @stMsg,hWinMain,0,0
                                        .break .if eax == WM_QUIT
                                        invoke        TranslateMessage,addr @stMsg
                                        invoke        DispatchMessage,addr @stMsg
                        .endw
               
                        ret
_WinMain        endp
       
       
       
       
       
       
               
start:
               
                call _WinMain
                invoke ExitProcess,NULL

       
       
       
       
       
                end start

99101553@qq.com 发表于 2016-8-27 11:24:04

_ProcWinMain        proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
                                local        @stPs:PAINTSTRUCT   
                                local        @stRect:RECT
                                local        @hDc:HDC
                               
                                mov         eax,uMsg
                               
                                .if                eax == WM_PAINT
                                                invoke        BeginPaint,hWnd,addr @stPs
                                                mov                @hDc,eax
                                               
                                                invoke        GetClientRect,hWnd,addr @stRect
                                                invoke        DrawText, @hDc , addr szText,-1,\
                                                                addr @stRect,\
                                                                DT_SINGLELINE or DT_CENTER or DT_VCENTER
                                                invoke        EndPaint,hWnd,addr @stPs
                                .elseif        eax ==WM_CLOSE
                                                invoke        PostQuitMessage,NULL
                                                invoke        DestroyWindow,hWinMain
                                                invoke         ExitProcess,NULL                      ;在这里加入,才可以完全退出程序
                                .else
                                                invoke        DefWindowProc,hWnd,uMsg,wParam,lParam
                                                ret
                                .endif
                                xor         eax,eax
                                ret
_ProcWinMain endp

99101553@qq.com 发表于 2016-8-27 12:03:37

找到原因
GetMessage:

Return value
Type: Type: BOOL
If the function retrieves a message other than WM_QUIT, the return value is nonzero.
If the function retrieves the WM_QUIT message, the return value is zero.

;*****************************************************
;消息循环
;*****************************************************
                        .while TRUE
                                        invoke         GetMessage,addr @stMsg,hWinMain,0,0
                                        ;.break .if eax == WM_QUIT
                                        .break         .if        eax == 0
                                        invoke      TranslateMessage,addr @stMsg
                                        invoke      DispatchMessage,addr @stMsg
                        .endw
               

99101553@qq.com 发表于 2016-8-27 12:54:53

如果   加入判断 WM_CLOSE和WM_DESTROY   为什么消息循环不能退出??????
好像 PostQuitMessage 没有执行一样
_ProcWinMain        proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
                                local        @stPs:PAINTSTRUCT   
                                local        @stRect:RECT
                                local        @hDc:HDC
                               
                                mov         eax,uMsg
                               
                                .if                eax == WM_PAINT
                                                invoke        BeginPaint,hWnd,addr @stPs
                                                mov                @hDc,eax
                                               
                                                invoke        GetClientRect,hWnd,addr @stRect
                                                invoke        DrawText, @hDc , addr szText,-1,\
                                                                addr @stRect,\
                                                                DT_SINGLELINE or DT_CENTER or DT_VCENTER
                                                invoke        EndPaint,hWnd,addr @stPs
                                .elseif        eax == WM_CLOSE
                                                invoke         MessageBox,hWinMain,offset szQuitText,offset \
                                                                szCaptionMain,MB_OKCANCEL
                                                .if                eax == IDOK
                                                                invoke        DestroyWindow,hWinMain
                                                                ret
                                                .endif
                                .elseif        eax == WM_DESTROY
                                                invoke        PostQuitMessage,NULL
                                                ret
                                .else
                                                invoke        DefWindowProc,hWnd,uMsg,wParam,lParam
                                                ret
                                .endif
                                xor         eax,eax
                                ret
_ProcWinMain endp

99101553@qq.com 发表于 2016-8-27 13:22:17

99101553@qq.com 发表于 2016-8-27 12:03
找到原因
GetMessage:



改了,,还是一样没有退出循环,{:5_94:}
这是怎么回事????
请帮忙!!!!!!

99101553@qq.com 发表于 2016-8-27 13:51:50

;*****************************************************
;消息循环
;*****************************************************
                        .while TRUE
                                       ; invoke         GetMessage,addr @stMsg,hWinMain,0,0
                                        ;.break .if eax == WM_QUIT
                                        invoke         GetMessage,addr @stMsg,NULL,0,0
                                        .break         .if          eax == 0
                                        invoke      TranslateMessage,addr @stMsg
                                        invoke      DispatchMessage,addr @stMsg
                        .endw

把NULL 改成 程 序 句柄hInstance程序运行报错!窗口句柄可以用但在DestroyWindow 之后,GetMessage 无法改得 窗口的消息,所以消息循环就不能退出!
页: [1]
查看完整版本: Win32 汇编例程问题?