琢石成器WIN32汇编程序设计学习(六)-WNDCLASSEX
本帖最后由 兰陵月 于 2018-3-13 23:17 编辑第一段代码,变量定义
;------------------------------------------------------------------------
; 可读可写未初始化变量
;------------------------------------------------------------------------
.data?
;------------------------------------------------------------------------
hInstance dd ?
hWinMain dd ?
hMenu dd ?
;------------------------------------------------------------------------
; 可读不可写初始化常量
;------------------------------------------------------------------------
.const
;------------------------------------------------------------------------
szClassName db "MyClass",0
szCaptionMain db "鱼C论坛-汇编语言交流-by 兰陵月",0
szText db "鱼C论坛好!鱼C论坛妙!鱼C论坛呱呱叫!",0
szMainMenu db 'MainMenu'
;------------------------------------------------------------------------
第二段代码,WNDCLASSEX结构(C++语法表示)
【C++】
typedef struct tagWNDCLASSEX {
UINT cbSize;//ok
UINT style;//ok
WNDPROC lpfnWndProc;//ok
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;//ok
HICON hIcon;
HCURSOR hCursor;//ok
HBRUSH hbrBackground;//ok
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;//ok
HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;
第三段代码,注册窗口类(WIN32汇编语言)
;------------------------------------------------------------------------
_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
invoke LoadMenu,hInstance,offset szMainMenu
mov hMenu,eax
mov @stWndClass.lpszMenuName,offset szMainMenu
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_MENU + 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,hMenu,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
按照上图中红框内的意思,如果在注册类的时候定义了菜单选项,则第三段代码第32行处的参数“hMenu”改为NULL,窗口仍然会显示菜单。
再根据上图中标示处的内容,必须要得到菜单的句柄。
所以
然后将WNDCLASSEX结构的lpszMenuName字段变为菜单句柄值,即
mov @stWndClass.lpszMenuName,eax
编译成功,但是运行程序发生了错误。如下图:
这说明,WNDCLASSEX结构中的字段填写方式是错误的,不能填写菜单句柄值。
经尝试,方法1:
在资源文件中,将菜单值更改为数值型的ID值,如下图:
然后在asm源程序中,同样等值定义好相关符号,如下图:
并在注册类填充WNDCLASSEX结构字段时,将菜单ID值填入,如下:
mov @stWndClass.lpszMenuName,IDM_MAIN
程序可以正常运行,如下图:
方法2:在资源文件中和源程序中将菜单ID改为字符串形式,然后将字符串地址填入WNDCLASSEX相关字段,也同样可以通过。如下:
mov @stWndClass.lpszMenuName,offset szMainMenu.
所以下图中的表述是不准确的,或者是不详细的!
可以666666 会魔法的魔法 发表于 2018-3-14 08:53
可以666666
{:10_266:}{:10_266:}{:10_266:}
初学,喜欢各种情况都鼓捣一下! WNDCLASSEX.lpfnWndProc offset _ProcWinMain
_ProcWinMain proc uses ebx edi esi hWnd, uMsg, wParam, lParam
这段代码里的 uses ebx edi esi hWnd, uMsg, wParam, lParam 传值和顺序有些一知半解 能帮我讲解一下吗?
uses ebx edi esi
是压入寄存器。相当于函数开始时PUSH,函数返回前POP这三个寄存器。
hWnd是指向窗口的指针,uMsg是指向消息的指针,wParam、lParam是MSG结构体里面的两个参数啊
传递顺序是stdcall形式,从右向左。
页:
[1]