Win32编程

WinMain函数的结构: GetModuleHandle -> RtlZeroMemory -> LoadCursor -> RegisterClassEx -> CreatWindowEx -> ShowWindow -> UpdateWindow -> CreateWindowEx创建窗口,ShowWindow则把窗口显示在屏幕上

GetMessage -> TranslateMessage -> DispatchMessage 这是和消息有关的循环,叫消息循环

在屏幕上显示一个窗口的过程: 1.得到应用程序的句柄(GetModuleHandle) 2.注册窗口类(RegisterClassEx)。在注册之前,要先填写RegisterClassEx的参数WNDCLASSEX结构。 3.建立窗口(CreateWindowEx)。 4.显示窗口(ShowWindows)。 5.刷新窗口客户区(UpdateWindow) 6.进入无限的消息获取和处理的循环。首先获取消息(GetMessage),如果消息到达,则将消息分派到回调函数(DispatchMessage),如果消息是WM_QUIT,则推出循环。

取模块句柄使用的API函数是GetModuleHandle,使用方法是: invoke GetModuleHandle,lpModuleName lpModuleName参数是一个指向含有模块名称字符串的指针,可以用这个函数取得程序地址空间中各个模块的句柄 例如: szUserDll db 'User32.dll',0  invoke GetModuleHandle,addr szUserDll  .if eax   mov hUserDllHandle,eax  .endif

如果使用参数NULL调用GetModuleHandle,那么得到的是调用者本模块的句柄,我们可以这样使用 invoke GetModuleHandle,NULL mov hInstance,eax

注册窗口类的API函数是RegisterClassEx,最后的Ex是扩展的意思,一个窗口类定义了窗口的一些主要属性,这些属性是定义在一个WNDCLASSEX结构中,再把结构的地址当参数一次性传给RegisterClassEx WNDCLASSEX STRUCT  cbSize  dword ? :结构的字节数  Style  dword ? :类的风格  LpfnWndProc dword ? :窗口过程的地址  cbClsExtra dword ? :  cbWndExtra dword ? :  HInstance dword ? :所属的实例句柄  HIcon  dword ? :窗口图标  HCursor  dword ? :窗口光标  HbrBackground dword ? :背景色  LpszMenuName dword ? :窗口菜单  LpszClassName dword ? :类名字符串的地址  HIconSm  dword ? :小图标 WNDCLASSEX ENDS 实例:  local @stWndClass:WNDCLASSEX ;  ...  invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass  invoke LoadCursor,0,IDC_ARROW  mov @stWndClass.hCursor,eax  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_WINDOW+1  mov @stWndClass.lpszClassName,offset szClassName  invoke RegisterClassEx,addr @etWndClass 解释:RtlZeroMemory将变量@stWndClass全填为零 hIcon 图标句柄,指定在窗口标题栏左上角的图标,widows已经预定义了一些图标,程序可以使用资源文件中定义的图标,用LoadIcon函数获得 hCursor 光标句柄,指定了鼠标在窗口中的光标形状,widows也预定义了一些光标,可以用LoadCursor获得他们的句柄,IDC_ARROW是windows预定义的箭头光标,如果想使用自定义的光标,也可以使用资源文件 lpszMenuName 指定窗口上显示的默认菜单,他指向一个字符串,描述资源文件中的名称,如果资源文件中菜单是用数值定义的,那么这里使用菜单资源的数值,窗口菜单也可以在建立窗口函数CreateWindowEx的参数中指定 hInstance 指定要注册的窗口类属于哪个模块,用GetModuleHandle获得 cbSize 指定WNDCLASSEX结构的长度,用sizeof伪操作来获取 style 窗口风格,CS_HREDRAW,CS_VREDRAW表示窗口的宽度或高度改变时是否重画窗口。比较重要的是CS_DBLCLKS,指定了他,windows才会把窗口中快速两次单击鼠标的行为翻译成双击消息WM_LBUTIONDBLCLK发给窗口过程。 hbrBackground 窗口客户区的背景色。hbr表示他是一个刷子(Brush)的句柄,windows预定义了一些刷子,如BLACK_BRUSH,WHITE_BRUSH等,可以用下列语句来得到他们的句柄:  invoke GetObjectStocx,WHITE_BRUSH 在这里也可以使用颜色值,windows已经预定义了一些颜色值,COLOR_BACKGROUND,COLOR_HIGHLIGHT,COLOR_MENU,COLOR_WINDOW等使用这些颜色值时,windows规定必须在颜色值上加1  mov @stWndClass.hbrBackground,COLOR_WINDOW+1 lpszClassName 指定程序员要建立的类命名,方便以后用这个名称来引用他 cbWndExtra,cbClsExtra分别是在windows内部保存的窗口结构和类结构中给程序员预留的空间大小,用来存放自定义的数据,他们的单位是字节,不使用的话,这两个就是0 lpfnWndProc 最重要的参数,他指定了基于这个类建立的窗口的窗口过程地址,通过这个参数,windows就知道了在DispatchMessage函数中把窗口消息发到哪里去,一个窗口过程可以为多个窗口服务,只要这些窗口是基于同一个窗口类建立的, ****强烈建议用or,不要用+

建立窗口:CreateWindowEX invoke CreateWindowEx,dwExStyle,lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu, hInstance,lpParam lpClassName 建立窗口使用的类名字符串指针,在FirstWindow中指向MyClass字符串表示使用MyClass类建立的窗口,这里可以是windows预定义的类名 lpWindowName 指向表示窗口名称的字符串,该名称会显示在标题栏上,如果该参数空白,则标题栏上什么都没有 hMenu 窗口上要出现的菜单的句柄,在注册窗口类的时候也定义了一个菜单,那是窗口默认的菜单,当建立的窗口是子窗口时,(dwStyle指向了WS_CHILD),这个参数是另一个含义,这时hMenu参数指定的是子窗口的ID号 lpParam 这是一个指针,指向一个欲传给窗口的参数,这个参数在WM_CREATE消息可以被获取,一般情况不用 hInstance 模块句柄,和注册窗口类时一样,指定了窗口所属的程序模块 hWndParent 窗口所属的父窗口 x,y 指定窗口左上角位置,默认时可以指定为CW_USEDEFAULT nWidth,nHeight 窗口的高度,宽度也可指定为CW_USEDEFAULT dwStyle,dwExStyle决定了窗口的外形和行为 dwStyle的定义,它们是以WS(WINDOW STYLE的缩写)为开头的预定义值 WS_OVERLAPPED 普通的重叠式窗口 WS_POPUP 弹出式窗口 WS_CHILD 子窗口 WS_MINIMIZE 初始状态是最小化的 WS_VISIBLE 初始状态是可见的 WS_DISABLED 初始状态是被禁止的 WS_MAXIMIZE 初始状态是最大化的 WS_BORDER 单线条边框 WS_DLGFRAME 对话框类型的边框 WS_VSCROLL 垂直滚动条 WS_HSCROLL 水平滚动条 WS_SYSMENU 带系统菜单 WS_THICKPRAME 可以拖动调整大小的边框 WS_MINIMIZEBOX 有最小化按钮 WS_MAXIMIZEBOX 有最大化按钮

WS_CHILDWINDOW WS_CHILD WS_TILED WS_OVERLAPPED WS_OVERLAPPEDWINDOW WS_OVERLAPPED OR WS_CAPTION OR WS_SYSMENU OR WS_THICKFRAME OR    WS_MINIMIZEBOX OR WS_MAXIMIZEBOX

dwExStyle是Win32扩展的,是一些以WS_EX_开头的预定义值,主要是一些特殊风格 WS_EX_TOPMOST  总在顶层的窗口 WS_EX_ACCEPTFILES 允许窗口进行鼠标拖放操作 WS_EX_TOOLWINDOW 工具边框 WS_EX_WINDOWEDGE 立体感的边框 WS_EX_CLIENTEDGE 客户区立体边框 WS_EX_OVERLAPPEDWINDOW WS_EX_WINDOWEDGE OR WS_EX_CLIENTEDGE WS_EX_PALETTEWINDOW WS_EX_WINDOWEDGE OR WS_EX_TOOLWINDOW OR WS_EX_TOPMOST WS_EX_PALETTEWINDOW可以很方便的构成浮在其他窗口前面的工具栏

ShowWindow函数主要控制窗口的显示状态(显示或隐藏),大小控制(最大化,最小化或原始大小)和是否激活,用窗口句柄做第一个参数,第二个参数是显示的方式 SW_HIDE   隐藏窗口,大小不变,激活状态不变 SW_MAXIMIZE  最大化窗口,显示状态不变,激活状态不变 SW_MINIMIZE  最小化窗口。。。。。。。。。。。。。。。 SW_RESTORB  从最大化或最小化恢复正常大小。。。。。。 SW_SHOW   显示并激活窗口,大小状态不变 SW_SHOWMAXIMIZED 显示并激活窗口,以最大化显示 SW_SHOWMINIMIZED 显示并激活窗口,以最小化显示 SW_SHOWMINNOACTIVE 显示窗口并最小化,激活状态不变 SW_SHOWMA  显示窗口,大小状态不变,激活状态不变 SW_SHOWNOACTIVATE 显示并从最大化或最小化恢复正常大小,激活状态不变 SW_SHOWNORMAL  显示并激活窗口,恢复正常大小(初始化时用这个参数)

用UpdateWindow绘制客户区,它实际上就是向窗口发送了一条WM_PAINT消息,到此,一个顶层窗口就建立显示出来了

CreateWindowEx可以也用来建立子窗口,Windows中有很多预定义的子窗口类,如按钮和文本框的类名分别是 "Button"和"Edit"。要建立一个按钮,只要把lpClassName指向"Button"字符串就可以了

 

消息循环 其一般形式 .while TURE  invoke GetMessage,addr @stMsg,NULL,0,0  .break .if eax==0  invoke TranslateMessage,addr @stMsg  invoke DispatchMessage,addr @stMsg .endw

消息循环中的MSG结构 MSG STRUCT  hwnd dword ?  message dword ?  wParam dword ?  lParam dword ?  time dword ?  pt dword ? MSG ENDS

hwnd 消息要发向的窗口句柄 message 消息标识符 wParam 消息参数之一 lParam 消息参数之二 time 消息放入消息队列的时间 pt 这是一个POINT数据结构,表示消息放入消息队列时的鼠标坐标

GetMessage就是从消息队列中取出这样一条消息:  invoke GetMessage,lpMsg,hwnd,wMsgFilterMin,wMsgFilterMax 函数的lpMsg指向一个MSG结构,函数会在这里返回取得的消息,hWnd参数指定要获取哪个窗口的消息,例子指定为NULL,表示获取的是所有本程序所属窗口的消息,后两个参数为零表示获取所有编号的消息 如果获取的是WM_QUIT消息,那么eax中的返回值是0,否则返回非零值,所以用.break .if eax==0来检查返回值 TranslateMessage将MSG结构传给windows进行一些键盘消息的转换,有键盘按下和放开时,windows产生WM_KEYDOWN和WM_KEYUP或WM_SYSKEYDOWN和WM_SYSKEYUP,这些消息参数包含的时按键的扫描码,,因为不方便,所以TranslateMessage遇到键盘消息则将扫描码转换成ASCII码,并在消息队列中插入WM_CHAR或WM_SYSCHAR的消息,如此一来,只要处理WM_CHAR消息就好了,遇到别的则不处理

窗口过程 WindowProc proc hwnd,uMsg,wParam,lParam

wParam,lParam参数是消息所附带的参数,随消息的不同而不同,如:WM_MOUSEMOVE消息中,wParam是标志,lParam是鼠标的位置,在WM_GETTEXT消息中,wParam是要获取的字符数,lParam是缓冲区的地址,对于WM_COPY来说,它不需要额外的信息

消息: WM_CREATE 放置窗口初始化代码,如建立各种子窗口(状态栏和工具栏等) WM_SIZE 放置位置安排的代码,因为建立的子窗口可能需要随窗口大小的改变而移动位置 WM_PAINT 如果需要自己绘制客户区,则在这里安排代码 WM_CLOSE 向用户确认是否退出,如推出则摧毁窗口并发送WM_QUIT消息 WM_DESTROY 窗口摧毁,在这里放置释放资源等扫尾代码

DefWindowProc对一些消息的默认处理方式 WM_PAINT 擦除背景 WM_ERASEBKGND  WM_CLOSE 调用DestroyWindow摧毁窗口 WM_NCLBUTTONUP  WM_NCPAINT 非客户区绘制消息,将绘制边框和客户区

int wsprintf{  LPTSTR lpOut,//输出缓冲区的地址  LPCTSTR lpFmt//格式化串地址  ...      //变量列表 }

使用右键弹出菜单: 由TrackPopupMenu,hMenu,uFlags,x,y,nReserved,hWnd,lpRect实现。 执行后,在参数指定的x,y位置弹出一个属于hWnd窗口(也就是WM_COMMAND消息发到这个窗口)的菜单,菜单句柄是hWnd,坐标是以整个屏幕左上角为基准的,uFlag参数指定一些和位置有关的选项,可以是:PM_CENTERALIGN,TPM_LEFTALIGN,TPM_RIGNTALIGN三者之一,表示(x,y)代表弹出菜单位置中间,左上角,还是右上角,一般习惯用TPM_LEFTALIGN,这样,菜单会在鼠标点击处的右边弹出。uFlag同时还可以指定用鼠标右键还是左键选定菜单项,定义值可以是TPM_LEFTBUTTON,TPM_RIGHTBUTTON,如果是TPM_RIGHTBUTTON,在菜单项按鼠标左键是没有反应的 lpRect指向一个RECT结构,用来指定一个区域,当菜单弹出后,在这个区域外单击,菜单才会消息,用NULL就可以了 调用此函数前,要调用invoke GetCursorPos,lpPoint lpPoint是一个POINT数据结构,含两个子项,x,y invoke GetSubMenu,hMenu,nPos .if eax  mov hSubMenu,eax .endif

local stPos,POINT invoke GetCursorPos,addr stPos invoke TrackPopupMenu,hSubMenu,TPM_LEFTLIGN,stPos.x,stPos.y,NULL,hWnd,NULL 对菜单项状态的检测可以用invoke GetMenuState,hMenu,uID,uFlags hMenu,菜单句柄,uID,用来检测的菜单项,当uFlag是MF_BYCOMMAND的时候,uID用菜单ID指定,当uFlag是MF_BYPOSTTION时,uID的位置是索引,返回值为-1时表示失败,否则会是MF_CHECHED,MF_DISABLED,MF_GRAYED,MF_HILITE,MF_MENUBARBREAK,MF_MENUBREAK,MF_SEPARATOR,的组合值,它们分别表示菜单项的状态是选中,禁用,灰化,高亮显示已经3种分隔线,可以用test指令测试相应的数据位来分辨菜单项处于哪个状态 invoke GetMenuState,hMenu,IDM_XXX,MF_BYCOMMAND .if eax & MF_CHECKED;表示此菜单项是选中状态 .endif 设置菜单项可以用 invoke EnableMenuItem,hMenu,uIDEnableItem,uEnable invoke CheckMenuItem,hMenu,uIDCheckItem,uCheck invoke CheckMenuRadioItem,hMenu,idFirst,idLast,idCheck,uFlags EnableMenuItem可以将菜单项在禁用,可用,灰化之间切换 uEnable可以取值:MF_DISABLED,MF_ENABLED,MF_GRAYED CheckMenuItem可以在非互斥的选定状态和非选定状态之间切换 nCheck的取值:MF_CHECKED,MF_UNCHECKED CheckMenuRadioItem可以在互斥的选定状态和非选定状态之间切换,idFirst,idLast指定这个互斥范围,

要在标题栏设置图标可以向窗口发送WM_SETICON消息 invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,hIcon,wParam可以是ICON_BIG,ICON_SMALL

 

 

 

作为Microsoft 32位平台的应用程序编程接口,Win32 API是从事Windows应用程序开发所必备的。本书首先对Win32 API函数做完整的概述;然后收录五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务;在附录部分,讲解如何在Visual Basic和Delphi中对其调用。 本书是从事Windows应用程序开发的软件工程师的必备参考手册。 Win32 API作为 Microsoft 32位平台(包括:Windows 9x,Windows NT3.1/4.0/5.0,WindowsCE)的应用程序编程接口,它是构筑所有32位Windows平台的基石,所有在Windows平台上运行的应用程序都可以调用这些函数。 从事Windows应用程序开发,离不开对Win32 API函数的调用。只有充分理解和利用API函数,才能深入到Windows的内部,充分挖掘系统提供的强大功能和灵活性。 近年来,随着Microsoft 32位平台的版本升级, Win32 API函数的构成、功能与调用方式都有很大的发展变化,然而,国内很少有相关的新版资料出版。为了满足广大开发人员的迫切需求,我们经过认真收集、整理素材,组织编写了这本与各种Microsoft 32位平台最新版本同步的Win32 API参考手册。 全书收录了五大类函数:窗口管理、图形设备接口、系统服务、国际特性以及网络服务。所有函数均附有功能说明、参数说明、返回值说明、备注以及引用说明。另外,在本书的第一章,我们对WiN32 API函数作了完整的概述;在附录部分,讲解了如何在Visual Basic和Delphi中对其调用。 由于篇幅较大,涉及技术内容广泛,加之时间仓促,书中难免存在不少错误或疏漏,希望广大读者给与批评指正。 在Windows程序设计领域处于发展初期时,Windows程序员可使用的编程工具唯有API函数。这些函数在程序员手中犹如"积木块"一样,可搭建出各种界面丰富、功能灵活的应用程序。不过,由于这些函数结构复杂,所以往往难以理解,而且容易误用。 随着软件技术的不断发展,在Windows平台上出现了很多优秀的可视化编程环境,程序员可以采用"所见即所得"的编程方式来开发具有精美用户界面和功能的应用程序。这些可视化编程环境操作简便、界面友好,比如:Visual C++,Delphi,Visual Basic等等。在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能。事实上,这些类库和控件都是构筑在Windows API的基础上的,但它们使用方便,加速了Windows应用程序的开发,所以受到程序员的普遍采用。有了这些类库和控件,程序员们便可以把主要精力放在整体功能的设计上,而不必过于关注具体细节。不过,这也导致了非常多的程序员在类库面前"固步自封",对下层API函数的强大功能一无所知。 实际上。程序员要想开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数。虽然类库和控件使应用程序的开发容易得多,但它们只提供Microsoft Windows的一般功能,对于一些比较复杂和特殊的功能来说,单使用类库和控件是难以实现的,必须直接使用API函数来编写。API函数是构筑整个Windows框架的基石,只有充分理解和利用API函数,才能深入到Windows的内部,充分发挥各种32位平台的强大功能和灵活性,才能成功地扩展和突破类库、控件和可视开发环境的限制。 Win32 API即为Microsoft 32位平台的应用程序编程接口(Application Programming Interface)。所有在Win32平台上运行的应用程序都可以调用这些函数。 使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Mircrosoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。 在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。 标准Win32 API函数可以分为以下几类: 窗口管理 窗口通用控制 Shell特性 图形设备接口 系统服务 国际特性 网络服务 在下面各节中,我们分别介绍这7种类型的API函数。 窗口管理函数向应用程序提供了一些创建和管理用户界面的方法。你可以使用窗口管理函数创建和使用窗口来显示输出、提示用户进行输入以及
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值