第四章 第一个窗口程序

一。主程序:
(1) GetModuleHandle:获取模块句柄
        invoke GetModuleHandle,lpModuleName
         lpModuleName参数是一个指向含有模块名称字符串的指针。此参数为NULL的时候,返回的是调用者本身模块的句柄。
一般返回值都放在hInstance而不是hModule,因为一个可执行文件运行后形成的”模块“,多次加载同一个可执行文件时候,这个模块是公用的。为了区分多次加载的拷贝,就把每个拷贝称为实例instance。 但是win32中程序运行的时候是隔离的,不存在模块的多个 实例的问题,所以实际上win32中,实力句柄就是模块句柄。
(2) RegisterClassEx:注册窗口类
    invoke RegisterClassEx,addr    @stWndClass
@stWndClass是一个以WNDCLASSEX为数据结构的变量,LOCAL @stWndClass:WNDCLASSEX
结构体中由建立窗口类的各种参数;
  • hIcon:图标句柄,指定显示在窗口标题栏左上角的图标。使用LoadIcon
  • hCursor:光标句柄。LoadCursor,预定义为IDC_ARROW,invoke LoadCursor,0,IDC_ARROW   注意中间是0,参数是hInstance,但是这里要是0 不然的话鼠标在客户区会是漏斗,碰到标题栏才会变成箭头
  • lpszMenuName:指定窗口的菜单,指向一个字符串,描述资源文件中菜单的名称。也可以才建立窗口函数中指定,详见步骤(3)
  • hInstance:指定要注册的窗口类属于哪一个模块
  • cbSize:指定WNDCLASSEX结构的长度,直接赋值mov @stWndClass,sizeof WNDCLASSEX
  • style:窗口风格。CS_HREDRAW or CS_VREDRAW,分别指定在窗口宽高改变的时候重画窗口redraw。CS_DBLCLKS风格,指定了它,windows才会把窗口中快速的两次单机鼠标的行为结束为双击消息WM_LBUTTONDLBCLK发给窗口过程。
  • hbrBackground:窗口客户区的颜色,hbr表示它是一个刷子的句柄。通过invoke GetStockObject,WHITE_BRUSH得到。也可以直接使用系统预定义的颜色值,COLOR_BACKGROUND,COLOR_HIGHLIGHT,COLOR_MENU,COLOR_WINDOW,调用的时候再颜色值上+1。mov @stWndClass.hbrBackgound,COLOR_WINDOW+1
  • lpszClassName:指定类名,是一个指向字符串的指针
  • cbWndExtra和cbClsExtra:分别是在windows内部保存的窗口结构和类结构中被程序员预留的自定义空间。
  • lpfnWndProc:指定基于这个类建立的窗口的窗口过程地址。之后DispatchMessage就将窗口消息发给这个程序。
(3) CreateWindowsEx:建立窗口。可以进一步的在用窗口类建立真实窗口的时候添加一些特定属性。
invoke    CreateWindowEx,dwExStyle,lpClassName,lpWindowName,dwStyle,x,y,nwidth,nHeight,hWndParent,hMenu,hInstance,lParam
  •  lpClassNmae:建立窗口使用的窗口类的类名字字符串指针
  • lpWindowName:指向窗口名称的字符串指针
  • hMenu:菜单句柄。当建立的窗口是子窗口的时候,dwStyle指定WS_CHILD,因为子窗口没有菜单,所以这个参数变成指定子窗口的ID号,可以节省参数位置
  • lpParam:指针,指向一个欲传给窗口的参数,一般不用
  • x,y,nWidth,nHeight:窗口的在左上角位置,单位像素,以及默认大小
  • dwStyle和dwExStyle指定窗口的外形和行为:dwStyle 都是以WS(window style 开头)WS_OVERLAPPERD 普通重叠式窗口,WS_SYSMENU带系统菜单(即带标题栏左上角的图标),WS_THICKFRAME可以拖动调整边框大小,WS_OVERLAPPEDWINDOW(多个风格合起来);dwExStyle是扩展以WS_EX_开头,WS_EX_WINDOWEDGE 立体感的边框,WS_EX_CLIENTEDGE 客户区立体边框 WS_EX_OVERLAPPEDWINDOW  是前两者的合成
(4) ShowWindow:
invoke ShowWindow ,hWinMain, SW_SHOWNORMAL
hWinMain是前面createwindowex建立窗口返回的句柄,SW_SHOWNORMAL 显示并激活窗口,恢复正常大小
(5) UpdateWindow:绘制客户区,相当于向窗口发送WM_PAINT消息
(6)消息循环:
  • GetMessage:
invoke GetMessage ,lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax
lpMsg指向一个MSG结构,函数会在这里返回所取到的消息。hWnd参数是到哪个窗口去获取消息,指定 NULL就是获取本程序所属窗口的所有消息 。(不指定NULL,将会程序窗口关闭,但是线程关闭不了)
wMsgFilterMin, wMsgFilterMax 会筛选这个范围内的消息,都是0表示接受所有编号消息。
MSG结构包含 hwnd 消息发向的窗口,Message消息标识符,WM_开头的预定义值,wParam和lParam消息参数,pt是一个POINT数据结构,表示消息放入消息队列时的鼠标坐标
  • TranslaMessage:遇到键盘消息的扫描码,转换成常用的ASCII码并在消息队列中插入WM_CHAR或者WM_SYSCHAR消息。
  • DispatchMessage:将消息发往相应的窗口过程

GetMessage和PeekMessage
windows是抢占式的多任务系统系统,任务之间每20ms切换一次,若果轮到程序的20ms时间片的时候,如果改程序队列中没有消息的话,windows就没收这20ms时间片,程序已然停留在GetMessage内部,保证了CPU资源的合理利用。
PeekMessage与其类似,区别在与当消息队列中由消息的时候,PeekMessage取回消息,并在eax中返回非零值,没有消息返回eax=0。PeekMessage相对GetMessage在最后增加了一个参数,表示在取回消息后,对消息队列中的消息是否保留,参数为PM_NOREMOVE的时候,被取回的消息还在队列中,相当于偷看了消息。

模块:代表一个运行中的exe文件或dll文件,用来代表这个文件所有的代码和资源。磁盘上的文件不是模块,装入内存后运行就叫做模块。一个应用程序调用其他DLL中的API的时候,这些DLL文件被装入内存,就产生了不同的模块。每个模块使用一个模块句柄来标识。
           在Win32中,模块句柄在数值上等于程序在内存中装入的地址。

二。窗口过程
WindowProc     proc    uses ebx edi esi hWnd,uMsg,wParam,lParam
                mov    eax,uMsg
                .if    eax==WM_XXX
                
                .elseif    eax==WM_XXX
                
                .elseif    eax==WM_CLOSE
                                 invoke DestroyWindow,hWinMain
                                invoke PostQuitMessage,NULL
                .else    
                             invoke DefWindowProc,hWnd,uMsg,wParam,lParam
                             ret            使用DefWindowProc函数一定要使用ret返回。
                   .endif
                   xor    eax,eax
                   ret
WindowProc    endp
1.窗口过程要保存ebx,edi,esi,ebp这四个寄存器,当指针使用,调用API后这些寄存器的值必改变
2 .uMsg参数指定的消息有一定的范围,Windows标准窗口预定义的值在0~03ffh之间,用户可以自定义,从0400h开始,WM_USER就定义为00000400h,当程序员定义多个用户消息的时候,一般使用WM_USER+1,WM_USER+2
3.WM_CLOSE代表用户有关闭窗口的意向,窗口过程有权不服从,但是WM_DESTORY的时候,窗口已经在关闭的过程当中了。
4.invoke wsprintf,addr szBuffer,addr    szReceive,lParam,lParam


三。窗口间通信
invoke SendMessage,hWnd,Msg,wParam,lParam
Windows在处理SendMessage的时候要检查消息类型,并对不同的消息做不同的处理。当消息的参数是一个32位数时,仅仅将数值传递给目标窗口过程,而当消息参数是一个指针的时候,Windows对指针的内容进行处理。
Windows首先创建一块共享内存,并将WM_SETTEXT消息lParam指向的字符串拷贝到该内存中,然后再发送消息到其他进程,并将共享内存在目标进程中的地址发给给目标窗口过程。最终共享内存会被释放。

WM_SETTEXT可以将参数所指向的字符串传递到目标窗口过程中,但消息有本职工作,且只能传递以0结尾的字符串。
WM_COPYDATA能够在不同进程的窗口间自由的拷贝任意类型的数据。该消息使用COPYDATASTRUCT结构来描述数据的长度和位置。
invoke SendMessage,hDestWnd,WM_COPYDATA,hWnd,addr stCopyData
WM_COPYDATA的wParam指定发送消息的hWnd,lParam 为一个COPYDATASTRUCT结构的变量。

PostMessage和SendMessage函数区别
Post函数将消息放入目标窗口的消息队列中并直接返回,函数返回后,目标窗口可能还没有处理到该消息。 
并且 Post函数不能处理任何参数中用到指针的消息,如刚才的WM_SETTEXT和WM_COPYDATA。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值