罗云彬的书第一个窗口程序的两个问题

qq_33892956 2016-03-13 10:35:39
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 4th Edition>
; by 罗云彬, luoyunbin@hotmail.com
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; FirstWindow.asm
; 窗口程序的模板代码
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff FirstWindow.asm
; Link /subsystem:windows FirstWindow.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include gdi32.inc
include user32.inc
include kernel32.inc

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?

.const
szClassName db 'MyClass',0
szCaptionMain db 'My first Window !',0
szText db 'Win32 Assembly, Simple and powerful !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
local @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
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.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
100,100,600,400,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret

_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start


问题一:如上,
.elseif	eax ==	WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL


这里sdk里面对应的代码是
case WM_DESTROY:
PostQuitMessage(0);
return 0;

为什么不一样?

问题二:
_ProcWinMain proc uses ebx edi esi ,hWnd,uMsg,wParam,lParam这里面为什么要有ebx edi esi?没见到下面的过程用到啊
...全文
129 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zara 2016-03-14
  • 打赏
  • 举报
回复
第一个,你放错位置了吧,要在最后的 .else 语句之前,和其它的 .elseif 并行。
第二个,更不应该了,除非是你写错了。
还有疑问,将这两个前后内容以及编译报错信息放上来看看。
qq_33892956 2016-03-14
  • 打赏
  • 举报
回复
引用 1 楼 zara 的回复:
问题一:看 WM_CLOSE 的说明,默认的处理就是调用 DestroyWindow();用户自己处理,至少可以用来确认下是不是真的要退出。所以,这样的处理,后果是一样的吧。 问题二:这个代码只是个最简单的示例,是没有用到;以后功能的扩展,用到的可能就多了,所以干脆一开始就写上,免得后面用到了却又忘了补上导致出错,要是一时没想到这个因素会纠结好久都不一定能明白症结所在。
我分别做过实验,问题一如果我这样写 .elseif eax == WM_DESTROY invoke PostQuitMessage,NULL 编译就通不过,按你的说法,就说不通 问题二同样,如果我这样写 _ProcWinMain proc hWnd,uMsg,wParam,lParam 同样报错
zara 2016-03-14
  • 打赏
  • 举报
回复
问题一:看 WM_CLOSE 的说明,默认的处理就是调用 DestroyWindow();用户自己处理,至少可以用来确认下是不是真的要退出。所以,这样的处理,后果是一样的吧。
问题二:这个代码只是个最简单的示例,是没有用到;以后功能的扩展,用到的可能就多了,所以干脆一开始就写上,免得后面用到了却又忘了补上导致出错,要是一时没想到这个因素会纠结好久都不一定能明白症结所在。
qq_33892956 2016-03-14
  • 打赏
  • 举报
回复
引用 7 楼 zara 的回复:
我是用 masm32v7 来做的,不是 vs,手头也没 vs。 如果还要坚持,将第二个有问题的 exe 上传来看看?
有你这句话就够了
zara 2016-03-14
  • 打赏
  • 举报
回复
我是用 masm32v7 来做的,不是 vs,手头也没 vs。
如果还要坚持,将第二个有问题的 exe 上传来看看?
qq_33892956 2016-03-14
  • 打赏
  • 举报
回复
引用 5 楼 zara 的回复:
你前面说是编译就出错,现在又说是运行了窗口看不见,没有的事,我试了都正常的显示退出;尤其是第一个,不可能影响到窗口显示的,对 WM_CLOSE 的处理不当,最多就是对正常退出响应异常。
我之前说编译报错是无意识的话语,不必计较。下面上图,我运行是按ctrl+f5,两个版本的程序明显不一样,我也不知道为啥
zara 2016-03-14
  • 打赏
  • 举报
回复
你前面说是编译就出错,现在又说是运行了窗口看不见,没有的事,我试了都正常的显示退出;尤其是第一个,不可能影响到窗口显示的,对 WM_CLOSE 的处理不当,最多就是对正常退出响应异常。
qq_33892956 2016-03-14
  • 打赏
  • 举报
回复
引用 3 楼 zara 的回复:
第一个,你放错位置了吧,要在最后的 .else 语句之前,和其它的 .elseif 并行。 第二个,更不应该了,除非是你写错了。 还有疑问,将这两个前后内容以及编译报错信息放上来看看。
第一个,我就是在原来的WM_CLOSE的位置上改的WM_DESTROY,报错是没报错,还显示成功了,但是点击运行什么都没发生,窗口也看不见。就这样。改回成WM_CLOSE就能正常运行。 第二个,改成_ProcWinMain proc hWnd,uMsg,wParam,lParam效果同第一个,什么都没发生

21,499

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧