马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 兰陵月 于 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.
所以下图中的表述是不准确的,或者是不详细的!
|