频道栏目
首页 > 资讯 > 其他 > 正文

Win32汇编从入门到入土(窗口程序)

18-08-01        来源:[db:作者]  
收藏   我要投稿

模块的概念

一个模块代表一个运行中的exe文件或dll文件,磁盘上的文件不是模块,装入内存运行时才叫做模块。因为一个应用程序需要调用多个API,因此包含这些API的dll文件(多个)会被装入内存,由此会产生多个模块,这时就需要模块句柄来标识不同的模块。

句柄概念

句柄只是一个数值,对程序来说没意义,只有Windows才知道句柄数值引用了什么,因为句柄是Windows给程序(文件、线程、模块都有句柄)编号的,并且这个“编号”在程序的每次运行可能都是不一样的,就好比你去超市购物,需要存包(程序运行),管理阿姨(Windows)需要给你一个号牌(句柄)。

窗口程序运行过程

1、获取应用程序(源文件)句柄(GetModuleHandle)

invoke GetMessage,lpModuleName(指针(标号),指向含有模块名称的地址,当设置为NULL时,返回调用者本模块的句柄)

2、配置窗口类结构(WNDCLASSEX)属性·,注册窗口类结构(RegisterClassEx)

WNDCLASSEX struct

hCoursor dword ;光标句柄,指定光标形状,用invoke LoadCursor,0,IDC_ARROW获取Windows预定义光标

hInstance dword ;指定注册的窗口属于哪个模块

cbSize dword ;指定WNDCLASSEX结构大小,用于区分版本

style dword ;窗口风格

lpfnWndProc dword ;最重要的参数,指定基于这个窗口的消息回调函数地址,通过这个参数,Windows知道了需要把窗口消息发到哪去

hbrBackground dword ;窗口客户区背景色,Windows预定了一些颜色(如BLACK_BRUSH,WHITE_BRUSH等),通过invoke GetStockObject,WHITE_BRUSH来得到他们的句柄,也可以直接使用窗口颜色值(如COLOR_BACKGROUND,COLOR_WINDOW等),但在使用时,必须用窗口颜色值+1

lpszClassName dword ;定义窗口类结构名,自己定义窗口类结构名,赋值标号,标号指向一个字符串

hIcon dword ;图标句柄,可以使用LoadIcon获取句柄

lpszMenuName dword ;指定窗口上显示默认菜单,指向一个字符串

hIconSm dword ;小图标

WNDCLASSEX ENDS

3、建立窗口(CreateWindowEx)

invoke CreateWindowEx,dwExStyle,lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,\

hInstance,lpParam

dwExStyle,dwStyle——这两个参数决定了窗口的外形和行为,dwStyle是从Win16就开始有的属性,dwExStyle是Win32中扩展的

常见的dwStyle定义 常见dwExStyle定义

lpClassName——指向窗口类结构的名称

lpWindowName——指向表示窗口名称的字符串,并将字符串显示在标题栏上

x,y——窗口启动时(左上角)在屏幕上的像素

nHeight,nWidth——窗口大小(高,宽)

hWndParent——建立的此窗口所属的父窗口,主要用来在父窗口关闭时,将子窗口关闭,如果要建立的是真正的子窗口(dwStyle参数为WS_CHILD时),这时,子窗口启动时位置会被限制在父窗口的客户区,同时子窗口的x,y也是以父窗口的左上角为基准

hMenu——窗口上要出现的菜单句柄,如果这里没有定义(NULL),而在窗口类结构中定义了,则使用窗口类结构中的菜单;如果这里定义了,不管注册内中是否定义,都将使用这里的定义,若两者没定义,则没有菜单

hInstance——模块句柄,指定窗口所属模块

lpParam——指向一个欲传给窗口的参数,这个参数在WM_CREATE消息中可以被获取,一般情况下用不到这个字段

4、显示窗口(ShowWindow)

窗口建立后,将返回窗口句柄,需要把它保存,以备后用,这时需要用ShowWindow把它显示出来。

invoke ShowWindow,窗口句柄,显示方式

5、刷新窗口客户区(UpdateWindow)

窗口显示后,用UpdateWindow绘制客户区,实际上这是向窗口发送一条WM_PAINT消息。

6、进入消息循环,无限获取(GetMessage从消息队列中获取消息,当消息是WM_QUIT时,GetMessage函数返回0,退出)和处理(DispatchMessage)消息

消息循环中,几个函数需要用到MSG结构,用来做消息传递

MSG STRUCT

hwnd dword ;消息要发向的窗口句柄

message dword ;消息标识符,以WM_开头

wParam dword ;消息参数之一

lParam dword ;消息参数之二

time dword

pt POINT <> ;POINT数据结构,表示消息放入消息队列时的鼠标坐标

MSG ENDS

 

invoke GetMessge,lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax

hWnd——指定要获取哪个窗口的消息,如果值为NULL,获取的是本程序所属窗口的消息

wMsgFilterMin,wMsgFilterMax——值为0表示获取所有编号的消息

PeekMessage是一个类似于GetMessage的函数,它拥有GetMessage所需的参数,并且还在最后增加了一个参数,用来表示在消息队列中取回消息后是否还要继续将消息保存在消息队列中,如果设置为PM_REMOVE,则当消息被取回的同时也要删除队列中的消息记录,当设置成PM_NOREMOVE时不会删除队列中的消息记录。

PeekMessage在消息队列中取回消息,返回非零值,如果消息队列中没有对应的消息记录,则返回零,然后当返回值是非零值时,可以在程序中检查消息是否为WM_QUIT,是则退出。

Window对消息的处理

在Windows系统中,存在一个记录系统所有消息的消息队列,当输入设备有所动作时,会产生相应的记录(消息类型,发生的位置,发生的时间)被Windows保存至队列中,此外Windows还会为每个程序维护一个单独的消息队列。Windows检查系统中总的消息队列,将记录派送到对应的程序消息队列中,当程序执行到GetMessage函数时,控制权转移到包含GetMessage函数的USER32.dll(箭头1),USER32.dll从程序消息队列取出一条消息(箭头2),将消息返回给应用程序(箭头3),程序执行到DispatchMessage回调函数,将消息交给子程序进行相应处理,控制权再次转移到USER32.dll(箭头4),DispatchMessage函数,找出消息记录对应窗口的处理子程序,然后调用他(箭头5),之后返回USER32.dll(箭头6),控制权再次交给程序(箭头7),程序循环,进行下一次消息处理。

相关TAG标签
上一篇:创建项目并集成Swagger (框架实战)
下一篇:mybatis报Error updating database. Cause: java.lang.IllegalArgumentException: invalid comparison: java错误的解决办法
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站