鱼C论坛

 找回密码
 立即注册
查看: 3166|回复: 4

[学习笔记] 琢石成器WIN32汇编程序设计学习(六)-WNDCLASSEX

[复制链接]
发表于 2018-3-13 22:43:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

001.jpg
按照上图中红框内的意思,如果在注册类的时候定义了菜单选项,则第三段代码第32行处的参数“hMenu”改为NULL,窗口仍然会显示菜单。
002.jpg
再根据上图中标示处的内容,必须要得到菜单的句柄。
所以
003.png
然后将WNDCLASSEX结构的lpszMenuName字段变为菜单句柄值,即
mov                @stWndClass.lpszMenuName,eax
编译成功,但是运行程序发生了错误。如下图:

004.png
这说明,WNDCLASSEX结构中的字段填写方式是错误的,不能填写菜单句柄值。
经尝试,方法1:
在资源文件中,将菜单值更改为数值型的ID值,如下图:
005.png
然后在asm源程序中,同样等值定义好相关符号,如下图:
006.png
并在注册类填充WNDCLASSEX结构字段时,将菜单ID值填入,如下:
mov        @stWndClass.lpszMenuName,IDM_MAIN
程序可以正常运行,如下图:
007.png

方法2:在资源文件中和源程序中将菜单ID改为字符串形式,然后将字符串地址填入WNDCLASSEX相关字段,也同样可以通过。如下:
mov        @stWndClass.lpszMenuName,offset szMainMenu.


所以下图中的表述是不准确的,或者是不详细的!
009.jpg

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-3-14 08:53:39 | 显示全部楼层
可以666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-3-14 09:02:15 | 显示全部楼层


初学,喜欢各种情况都鼓捣一下!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-3-14 22:37:26 | 显示全部楼层
WNDCLASSEX.lpfnWndProc offset _ProcWinMain

_ProcWinMain proc uses ebx edi esi hWnd, uMsg, wParam, lParam

这段代码里的 uses ebx edi esi hWnd, uMsg, wParam, lParam 传值和顺序有些一知半解 能帮我讲解一下吗?

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-3-16 14:29:55 | 显示全部楼层
uses ebx edi esi
是压入寄存器。相当于函数开始时PUSH,函数返回前POP这三个寄存器。
hWnd是指向窗口的指针,uMsg是指向消息的指针,wParam、lParam是MSG结构体里面的两个参数啊
传递顺序是stdcall形式,从右向左。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-6 06:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表