标签:
这是一个简单的记事本的窗口过程
1 WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 2 3 LOCAL winRect:RECT 4 LOCAL editWidth:DWORD 5 LOCAL editHeight:DWORD 6 7 .IF uMsg==WM_DESTROY 8 invoke PostQuitMessage,NULL 9 .ELSEIF uMsg==WM_CREATE 10 ;创建一个编辑框 11 invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset editClass,NULL,12 WS_CHILDWINDOW OR WS_VISIBLE OR WS_VSCROLL OR WS_HSCROLL OR WS_MAXIMIZE OR13 ES_AUTOHSCROLL or ES_AUTOVSCROLL or ES_MULTILINE ,14 0,0,300,300,hWnd,NULL,hInstance,NULL 15 mov hEdit,eax 16 17 .elseif uMsg==WM_SIZE 18 ;获取当前窗体的x,top,y,bottom 19 20 invoke GetClientRect,hWnd,addr winRect 21 22 ;计算出窗体的新宽度和高度 23 mov eax,winRect.right 24 sub eax,winRect.left 25 mov editWidth,eax 26 27 mov eax,winRect.bottom 28 sub eax,winRect.top 29 mov editHeight,eax 30 31 ;改变文本编辑框的宽度和高度 32 invoke MoveWindow,hEdit,0,0,editWidth,editHeight,TRUE 33 34 35 .ELSE 36 invoke DefWindowProc,hWnd,uMsg,wParam,lParam 37 ret 38 .ENDIF 39 40 xor eax,eax 41 ret 42 WndProc endp
API主要调用了CreateWindowEx,GetClientRect,MoveWindow
一些常用的窗口风格预定义值
窗口风格的预定义
预定义值 含义
WS_OVERLAPPED 普通的重叠式窗口
WS_POPUP 弹出式窗口(没有标题栏)
WS_CHILD 子窗口
WS_MINIMINZE 初始状态是最小化
WS_VISIBLE 初始状态是可见的
WS_DISABLED 初始状态是被禁止的
WS_MAXIMIZE 初始状态是最大化的
WS_BORDER 单线条边框
WS_DLGFRAME 对话框类型的边框
WS_VSCROLL 带垂直滚动条
WS_HSCROLL 带水平滚动条
WS_SYSMENU 带系统菜单(即带标题栏左上角的图标)
WS_THICKFRAME 可以拖动调整大小的边框
WS_MINIMIZEBOX 有最小化按钮
WS_MAXIMIZEBOX 有最大化按钮
为了容易理解,Window也为一些定义取了一些别名,同时,由于窗口的风格往往是几种风格的组合,所以Window
也预定义了一些组合值,如下:
等效的窗口风格预定义值
预定义值 等效值
WS_CHILDWINDOW WS_CHILD
WS_TILED WS_OVERLAPPED
WS_ICONIC WS_MINIMIZE
WS_SIZEBOX WS_THICKFRAME
WS_OVERLAPPEDWINDOW WS_OVERLAPPED or WS_CAPTION or WS_THICKFRAME or WS_MINIMIZEBOX or WS_MAXIMIZEBOX
WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
WS_POPUPWINDOW WS_POPUP or WS_BORDER or WS_SYSMENU
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
调用CreateWindowEx时窗口过程收到的消息
----------------------------------------------------------------------
消息发生 说明
------------------------------------------------------------------------------
WM_GETMINMAXINFO 获取窗口大小,以便初始化
WM_NCCREATE 非客户区开始建立
WM_NCCALCSIZE 非客户区大小
WM_CREATE 窗口建立
-----------------------------------------------------------------------
调用ShowWindow时窗口过程收到的消息
-------------------------------------------------------------------------------------------
消息发生 说明
-------------------------------------------------------------------------------------------
WM_SHOWWINDOW 显示窗口
WM_WINDOWPOSCHANGING 窗口位置准备改变
WM_ACTIVATEAPP 窗口准备激活
WM_NCACTIVATE 激活状态改变
WM_GETTEXT 取窗口名称(显示标题栏目)
WM_ACTIVATE 窗口准备激活
WM_SETFOCUS 窗口获取焦点
WM_ERASEBGND 需要擦除背景
WM_WINDOWPOSCHEANGED 窗口位置已经改变
WM_SIZE 窗口大小已经改变
WM_MOVE 窗口位置已经移动
--------------------------------------------------------------------------------------------------------------------------
调用DestroyWindow时窗口过程收到消息
---------------------------------------------------------------------------------------------------------------------
消息发生 说明
-----------------------------------------------------------------------------------------------------------
WM_NCACTIVATE 窗口激活状态
WM_ACTIVATE 窗口准备非激活
WM_ACTIVATEAPP 窗口准备非激活
WM_KILLFOCUS 失去焦点
WM_DESTROY 窗口即将被摧毁
WM_NCDESTROY 窗口的非客户区及所有子窗口已经被摧毁
-----------------------------------------------------------------------------------------------------------------------------------
DefWindowProc对一些消息的默认处理方式
-----------------------------------------------------------------------------------------------------------------------------------
消息 DefWindowProc的处理方式
---------------------------------------------------------------------------------------------------------------------------------
WM_PAINT 发送WM_ERASEBKGND消息来擦除背景
WM_ERASEBKGND 用窗口类结构中的hrBackground刷子来绘画窗口背景
WM_CLOSE 调用DestroyWindow来摧毁窗口
WM_NCLBUTTONDBLCLK 这是非客户区(如标题栏)鼠标双击消息,DefWindowProc测试鼠标的位置,然后再采
取相应的措施,如标题栏双击将最大化和恢复窗
WM_NCLBUTTONUP 这是非客户区鼠标释放消息,同样,DefWindowProc测试的位置然后再采用相相应的
措施,如鼠标在"关闭"按钮的位置释放将导致发送WM_CLOSE消息
WM_NCPAINT 非客户区绘制消息,DefWindowProc将绘制边框和客户区
--------------------------------------------------------------------------------------------------------------------------------------------------
窗口建立的过程
GetModuleHandle---------->RtlZeroMemory---->LoadCursor------>RegisterClassEx----->CreateWindowEx---->ShowWindow--->UpdateWindow
GetModuleHandle ;//得到窗口句柄
LoadMenu//得到窗口的菜单句柄
LoadAccelerator;//得到右键句柄
得到鼠标位置
GetCursorPos,addr @stPos;其中@stPos是 一个POINT类型的变量
不同应用程序之间的窗口是可以发送消息的,通过SendMessage或者PostMessage函数,用法如下:
invoke SendMessage ,hWnd,Msg,wParam,lParam
invoke PostMessage,hWnd,Msg,wParam,lParam
如果要改变窗口的光标,正确的办法是用SetClassLong函数改变窗口类的属性,这个函数的使用方法如下:
invoke SetClassLong,hWnd,nIndex,dwNewLong
这个函数用来改变窗口的属性,所以可以改变类中的光标设定,hWnd用来设定一个这个类建立的某个窗口句柄,nIndex参数指定要改变
窗口类的哪个属性,可以指定为GCL_HBRBACKGROUND,GCL_HCURSOR,GCL_HICON,GCL_HMODULE,GCL_MENUNAME,GCL_STYLE或GCL_WNDPROC等,
它们分别表示 要改变的窗口类的背景色、光标、图标、Hinstance,菜单、风格或窗口过程地址,读者可以用这个函数来改变一个窗口
类的几乎所有属性,程序中通过这个函数将窗口的光标在不同的光标句柄之间切换:
invoke SetClassLong,hWnd,GCL_HCUROSR,hCur1或hCur2
在资源脚本中定义的是控件的ID,当这些子窗口控件被创建以后同样会有一个窗口句柄,但既然它们不是由我们自己创建的,那么怎么知道它们的窗口
句柄呢?有一个函数可以从ID中获取句柄:
invoke GetDlgItem,hDlg,dwIDDlgItem
mov hDlgItem,eax
函数的输入参数是对话框和ID值,返回值是子窗口句柄:返过来,有两种方法可以从子窗口句柄获取ID:
(1) invoke GetDlgCtrlID,hWndCtrl;输入子窗口句柄,返回值是控件ID
(2) invoke GetWindoLong,hWndCtrl,GWL_ID
当需要向控件发送消息的时候,当然可以先用GetDlgItem获取子窗口句柄再用SendMessage函数,但有一个
更为简便:
invoke SendDlgItemMessage,hDlg,dwIDDlgItem,Msg,wParam,lParam
这个函数可以直接向控件发送消息,只需要在参数中指定对话框句柄和子窗口ID(注意,并没有PostDlgItemMessage这样的函数!)。
单选钮和复选框
单选钮和复选框都是基于Button类的,只不过它们的窗口分别是BS_RADIOBUTTON和BS_CHECKBOX.
既然它们是特殊“按钮”,所以和它们有关的函数都带有“Button"一词,查看一个单选钮或复选框是否可以
用下面的函数来检测:
invoke IsDlgButtonChecked,hDlg,nIDButton
函数的返回值可能是BST_CHECKED(选中状态),BST_INDETERMINATE(3态复选框的灰化状态)或BST_UNCHECKED(未选中状态)。也
可以用向子窗口控件发送BM_GETCHECK消息的方法来检测,返回值和上面的函数是一样的。
如果想设置单选按钮或复选框的状态,可以使用下面蝗语句:
invoke CheckDlgButton,hDlg,nIDButton,uCheck
参数uCheck用BST_CHECKED,BST_INDETERMINATE或BST_UNCHECKED来表示需要设置的状态,含义同上。向控件发送BM_SETCHECK消息
也可以取得同样的效果,这时消息的wParam中放置需要的状态。
复选框是不互斥的,所以 可随意主设置状态。而对于BS_RADIOBUTTON风格的单选按钮来说,并不是把某个按钮设置为选中以后,如果不是手动把同组的其他按钮全部
改为非选 中状态(逐个地调用 CheckDlgButton),就会看到同是圾两个单选钮是选 中的。但把同组的所有单选钮逐个地设置显得有点麻烦,所以针对单选钮有个专用函数:
invoke CheckRadioButton,hDlg,nIDFirstButton,nIDLastButton,nIDCheckedButton
文本编辑控件
文本编辑器是基于Edit类的控件,可以用缩写EDITTEXT定义,读者可以在文本编辑控件中输入并编辑文本。每当用户在文本编辑控件中输入一个字符的时候,控件就会向对话框过
程发送一个WM_COMMAND消息,所以在例子程序中,当在自定义文字的编辑框中每输入一个字,标题栏文字就会马上改变以。
当获取编辑框中的文本有多种方法,可以用GetWindowText,也可以用发送WM_GETTEXT消息的办法,要设置文本,同样可以用SetWindowText或发送WM_SETTEXT,但最简便的办法还是
使用下的函数:
invoke GetDlgItemText,hDlg,nIDDlgItem,ipString,nMaxCount;取文本
invoke SetDlgItemText,hDlg,nIDDlgItem,lpString;设置文本
在实际使用中,经常要在文本编辑控件中输入输出值型参数,将文本转换为数值比较麻烦,把数值转换为文本也要经过一个wsprintf调用,为了简化 操作,Windows提供了两个
函数来处理这个问题:
invoke GetDlgItemInt,hDlg,nIDDlgItem,uValue,bSigned;取控件中的数值
invoke SetDlgItemInt,hDlg,nIDDlgItem,lpTranslated,bSigned;设置控件中的数值
下面的例子将IDC_EDIT的输入最大长度定为10个字符:
invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_LIMITTEXT,10,NULL
invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETREADONLY,TRUE,NULL;只读
invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETREADONLY,FALSE,NULL;可写
滚动条
和其他子窗口控件发送WM_COMMAND消息不同,水平滚动条向对话框窗口发送WM_HSCROLL消息,而垂直滚动条则发送WM_VSCROLL消息,所以针动
对两种方式的滚动条分别处理不同的 消息:
WM_xSCROLL消息的参数如下所示:
wParam的低16位==nScrollCode;动作码
wParam的高16位== nPos;滚动条当前位置
lParam==hwndScrollBar;滚动条控件的窗口句柄
组合框
3种类型的组合框:
CBS_SIMPLE,CBS_DROPDOWN,CBS_DROPDOWNLIST
组合框 中还有几种常用的、可以附加的风格:
CBS_AUTOSCROLL 输入过长的文本时输入框自动卷动
CBS_LOWERCASE 自动将所有的文本转换成小写
CBS_SORT 自动将插入的文本项排序
CBS_UPPERCASE 自动将所有的文本转换成大写
组合框消息
消息 Wparam lParam 说明
CB_ADDSTRING 0 字符串地址 把一个字符串添加到列表中
CB_INSERTSTRING 位置索引 字符串地址 把一个字符插入到列表中
CB_FINDSTRING 开始查找的位置索引 查找的字符串 在列表中查找以lParam字符中开头的项,的巧劲则返回
位置索引,未找到返回CB_ERR
CB_FINDSTRINGEXACT 位置索引 查找的字符串 精确查找字符串
CB_DELTESTRING 位置索引 0 删除一个列表项
CB_RESTECONTEXT 0 0 删除所有了列表项
CB_GETLBTEXT 位置索引 缓冲区地址 获取指定列表项的字符串,缓冲必须足够大
CB_GETLBTEXTLEN 位置索引 0 获取指定列表项的字符串长度
CB_GETCOUNT 0 0 获取列表项的总数
CB_SETCURSEL 位置索引 0 选中一个列表项,并将列表项中的文字拷贝到编辑控件中
CB_SELECTSTRING 开始查找的位置索引 字符串地址 查找以lParam指定的字符中开始的列表项,如果找到则选中
中它将字符串拷贝到编辑框 中
CB_GETCURSET 0 0 获取当前选中位置索引,没有选中的项目则返回CB_ERR
CB_SHOWDROPDOWN 状态 0 打开(状态为TRUE)或收起(状为FALSE)下拉列表
CB_GETDROPEDSTATE 0 0 检测列表的当前下拉状态,返回TRUE表示拉下,FALSE表示收起
当用户在组合框中进行选 择操作时,Windows向对话框过程发送WM_COMMAND消息,消息中的WParam参数的低16位是组合框,高16位是通知码,用来表示
用户的操作,通知码的定义:
用户操作组合框后的通知码
通知码 说明
CBN_SELCHANGE 用户将要选择一个项目(鼠标移动到了这个项目上)
CBN_CLOSEUP 下拉列表关闭(可能是选 择完成也可能是取消选择)
CBN_SELENDOK 用户完成选择
CBN_SELENDCANCEL 用户取消选择(鼠标移动到了某个项目上,但并没有按下而是点击了其控件,或按动了ESC键)
CBN_DBLCLK 在CBS_SIMPLE的组合框中双击了一个列表项
CBN_DROPDOWN 用户打开了下拉框(按动了编辑框边的下拉按钮)
当列表框是LBS_NOTIFY风格的时候,用户有所动作时列表框 会向父窗口发送WM_COMMAND消息,同时在wParam的高16位中指定
通知码,列表框的通知码种类很少,基本上就是以下几种:
.LBN_DBLCLK 用户双击了一个项目
.LBN_ERRSPACE 插入项目时无法申请到足够的内在
.LBN_KILLFOCUS 输入焦点被切换到其他控件中列表丢失了焦点
.LBN_SELCANCEL 用户撤销了一个选择
.LBN_SELCHANGE 选定状态改变
.LBN_SETFOCUS 列表框得到了焦点
列表框通知父窗口是通过发送WM_COMMAND消息,而程序控制列表框的时候是通过向列表框发送消息来完成的,常用的列表框消息如下:
消息 wParam lParam 说明
LB_ADDSTRING 0 字符串地址 添加一个项目,返回加入后的索引
LB_DELETESTRING 位置索引 0 删除一个项目,返回剩余的项数
LB_FINDSTRING 开始索引 字符串地址 查找以字符串开头的项目,找到则返回位置索引,未找到则返回LB_ERR
LB_FINDSTRNGEXACT 开始索引 字符串地址 精确查找一个项目,返回值同上
LB_GETANCHORINDEX 0 0 返回多选列表框多选时的起始位置
LB_GETACRETINDEX 0 0 多选框中的当前焦点项目焦点位置
LB_GETCOUNT 0 0 返回列表框中的项目总数
LB_GETCURSETL 0 0 返回列表框中当前选中的项目
LB_GETSEL 位置索引 0 检测指定项目的选中状态,返回非0为选中,返回0为未选 中
LB_GETSELCOUNT 0 0 返回列表框中选中项目的总数
LB_GETSELLITEMS 最大项数 缓冲区地址 返回多选列表框的选中项目索引列表到缓冲区中
LB_GETTEXT 位置索引 缓冲区地址 返回某个项目的字符串
LB_GETTEXTLEN 位置索引 0 返回某个项目的字符串长度
LB_GETTOPINDEX 0 0 返回当前可见的第一个项目位置
LB_INSERTSTRING 插入位置 字符串地址 在指定位置插入一个项目
LB_RESETCONTENT 0 0 删除所有项目
LB_SELECTSTRING 开始位置 字符串地址 将以指定字符串开头的项目选 中
LB_SELITEMRANGE 选择状态 范围 在多选框中将一个范围选中或清除
LB_SETCURSEL 位置索引 0 在单选框中选 择一个项目
LB_SETSEL 选择状态 位置索引 在多选框中将一个项目选中或清除
LB_SETTOPINDEX 位置索引 0 滚动显示到指定的项目
LB_DIR 属性 文件通配符 搜索目录并将符合文件通配符的文件名加入到列表框中
在这些消息中LB_DIR 是个比较有趣的消息,它可以指定目录中的文件名自动列出来并加入到列表框中,如例子中用*.*将当前目录 的全冲毁文件名加到列表框中。LB_DIR
消息中wParam参数可以指定的属性可以是以下值的组合:
.DDL_ARCHIVE 加入归档属性的文件
.DDL_DIRECTORY 加入目录
.DDL_DRIVES 加入驱动器名
.DDL_HIDDEN 包含隐含文件
.DDL_READONLY 包含只读文件
.DDL_READWRITE 包含可读写的文件
.DDL_SYSTEM 包含系统文件
申请一个定时器使用SetTimer函数,函数的使用方法如下:
invoke SetTimer,hWnd,nIDEvent,uElapse,lpTimeFunc
hWnd参数是WM_TIMER消息发往的窗口句柄;nIDEvent参数是一个用户指定的任意整数,用来标识 一个程序中的多个定时 器
;uElapse是时间周期,以ms为单位,这个参数是必须指定的;lpTimerFunc是定时器过程。
撤消定时器的函数是KillTimer,该函数的使用方法:
invoke KillTimer,hWnd,uIDEvent
参数 hWnd,uIDEvent就是申请时用来的参数
申请定时器的有两个方法:
第一个:
invoke SetTimer,hWnd,ID_TIMER,250,NULL
这时参数lpTimeFunc必须为NULL
第二种:
invoke SetTimer,NULL,NULL,1000,addr _ProcTimer
把返回的值保存下来,以便注销是使用。
定时器过程如下定义:
TimeProc proc hwnd,uMsg,idEvent,dwTime
显示设备的颜色深度可以用以下函数获取:
invoke GetDeviceCaps,hDc,PLANES
mov ebx,dwPlanes
invoke GetDeviceCaps,hDc,BITSPIXEL
mul ebx
mov dwColorDepth,eax
第一个函数调用返回DC的色彩平面数,第二函数调用返回每个像素的色彩位数,
颜色深度最后可以通过dwPlanes乘以dwBitsPixel得到.
Window也提供了其他一些坐标映射方法供程序员使用,可以用SetMap Mode函数来为一个DC设置新的坐标映射方法:
invoke SetMapMode,hDc,iMapMode
参数iMapMode可以取下面的值:
Windows中可用的坐标映射方式
映射方法 原点 逻辑单位 X正方向 Y正方向
MM_TEXT(默认方式) 左上 像素 右 下
MM_HIENGLISH 左上 0.001英寸 右 上
MM_LOENGLISH 左上 0.001英寸 右 上
MM_HIMETRIC 左上 0.001毫米 右 上
MM_LOMETRIC 左上 0.1毫米 右 上
MM_TWIPS 左上 1/1440英寸 右 上
MM_ISOTROPIC 可变 可变(x=y) 可变 可变
MM_ANISOTROPIC 可变 可变(x!=y) 可变 可变
最后两种映射方式提供了更灵活了选择,设置为这两种映射方式后,程序可以继续调用SetViewPortOrgEx,SetViewportExtEx和
SetWindowExtEx函数来自由设置坐标系的原点,罗辑单位和坐标的正方向等所有参数,在其他映射方式下的时候,不能使用这
3个设置函数,这时任何对它们的调用都会被忽略.
---恢复内容结束---
标签:
原文地址:http://www.cnblogs.com/intothinair/p/4294487.html