《Windows程序设计》读书笔记之九

子窗口控制
                                                                                    见钱眼开 于 2005-5-5
       子窗口是什么?
       它其实就是一种窗口,基于窗口类创建,并且能够处理Windows消息。与顶级窗口有所不同的是,它创建之前必须确定一个父窗口。
       通过GetParent,子窗口可以确定父窗口的窗口句柄:
       hParent = GetParent(hChild);
       这样,它就可以向父窗口发送消息:
       SendMessage(hParent,message,wParam,lParam);
       message值取大于等于WM_USER的任意数值,这其实是在建立一个“子窗口控件”。当子窗口状态改变时,子窗口处理键盘和鼠标消息并通知父窗口。使用这种方法,我们就可以及时获知子窗口的状态改变。
       Windows已经预定义了一些可创建标准子窗口控件的窗口类。常见的如按钮、编辑框、组合框、列表框、滚动条等等。
       Windows预定义子窗口通常发送一条WM_COMMAND消息来通知父窗口。该消息的wParam参数高16位表示一个通知码,低16位表示一个子窗口ID(通过CreateWindow函数的 hMenu参数指定);lParam参数包含子窗口的窗口句柄。
       例如,“按钮”通知码的可能值在 Windows表头文件中定义如下:
 
按钮通知码标识符
BN_CLICKED
0
BN_PAINT
1
BN_HILITE or BN_PUSHED
2
BN_UNHILITE or BN_UNPUSHED
3
BN_DISABLE
4
BN_DOUBLECLICKED or BN_DBLCLK
5
BN_SETFOCUS
6
BN_KILLFOCUS
7
       当然,父窗口也可以发送消息来通知子窗口。这些消息包括以前缀 WM开头的许多消息;另外也可以是子窗口自定义的消息。
    例如, WINUSER.H中另外定义了8个按钮说明消息;前缀BM表示「按钮消息」。这些按钮消息如下表所示:
 
按钮消息
BM_GETCHECK
0x00F0
BM_SETCHECK
0x00F1
BM_GETSTATE
0x00F2
BM_SETSTATE
0x00F3
BM_SETSTYLE
0x00F4
BM_CLICK
0x00F5
BM_GETIMAGE
0x00F6
BM_SETIMAGE
0x00F7
       每个子窗口控件都具有一个在其兄弟中唯一的窗口句柄和ID值。对于句柄和ID这两者,知道其中的一个您就可以获得另一个。
       Id = GetWindowLong(hChild,GWL_ID);   //通过窗口句柄返回ID
       Id = GetDlgCtrl(hChild);                            //通过窗口句柄返回ID
       hChild = GetDlgItem(hParent,Id);             //通过ID返回窗口句柄
       根据不同的按钮风格,基于同一“按钮”窗口类,可以创建多种风格的按钮。
a)         下压按钮( BS_PUSHBUTTON BS_DEFPUSHBUTTON
       下压按钮控件主要用来触发一个立即响应的动作,而不保留任何形式的开/关指示。下压按钮控件有两种按钮风格,分别是BS_PUSHBUTTON和BS_DEFPUSHBUTTON。除设计对话框时两者功能上有些不同(BS_DEFPUSHBUTTON风格按钮响应Enter键,即使未获得输入焦点),用作子窗口控件时,两种风格按钮功能相同,尽管BS_DEFPUSHBUTTON的边框要粗一些。
       SendMessage (hwndButton, BM_SETSTATE, 1, 0) ;   //模拟按下按钮
       SendMessage (hwndButton, BM_SETSTATE, 0, 0) ;   //模拟弹起按钮
b)        复选框( BS_CHECKBOX 、BS_AUTOCHECKBOX、 BS_3STATE BS_AUTO3STATE
    复选框是一个文本框,文字通常出现在复选框的右边。复选框的常用功能如同一个开关:单击框一次将显示复选标记,再次单击清除复选标记。常用的两种风格是 BS_CHECKBOX和BS_AUTOCHECKBOX。对于BS_CHECKBOX风格的复选框,发送BM_SETCHECK消息显示或清除复选标记;而BS_AUTOCHECKBOX风格复选框触发复选标记的开和关。其余两种复选框风格是BS_3STATE和BS_AUTO3STATE,正如它们名字所暗示的,这两种风格能显示第三种状态-复选框内是灰色-它出现在向控件发送wParam等于2的WM_SETCHECK消息时。灰色是向使用者表示此框不能被选中或者禁止使用。
c)       单选按 钮(BS_RADIOBUTTON
       单选按钮的名称在按钮后面,单选按钮组常常用来表示相互排斥的选项。与复选框不同,单选按钮的工作与开关不一样,也就是说,当第二次按单选按钮时,它的状态会保持不变。
d)        分组框( BS_GROUPBOX
              分组框即风格为BS_GROUPBOX的选择框。不处理键盘和鼠标输入,不向父窗口 发送WM_COMMAND消息。常用来包含其它按钮控件。
 
    SetWindowText用以改变按钮(或者其它任何窗口)内的文字。对于一般窗口来说,这个文字是标题栏的文本;对于按钮控件来说,它是随着该按钮显示的文本。
       GetWindowText返回窗口文本。GetWindowTextLength返回窗口文本长度。
    ShowWindow显示或隐藏窗口。IsWindowVisible确定窗口是否可见。
       EnableWindow启用或禁用窗口。IsWindowEnabled确定窗口是否启用。
 
    当 Windows将输入焦点从一个窗口转换到另一个窗口时,它首先给正在失去输入焦点的窗口发送一个WM_KILLFOCUS消息,wParam参数是接收输入焦点的窗口的句柄。然后,Windows向正在接收输入焦点的窗口发送一个WM_SETFOCUS消息,同时wParam是还在失去输入焦点的窗口的句柄(在这两种情况中,wParam值可能为NULL,它表示没有窗口拥有或者正在接收输入焦点)。
    Windows保留了29种系统颜色以供各种显示使用。您可以使用GetSysColor和SetSysColors来获得和设定这些颜色。下表是按照COLOR_ 常数值(从0开始到28结束)顺序排列的系统颜色列表:
GetSysColor 和SetSysColors
系统登录键或WIN.INI标识符
内定的RGB值
COLOR_SCROLLBAR
Scrollbar
C0-C0-C0
COLOR_BACKGROUND
Background
00-80-80
COLOR_ACTIVECAPTION
ActiveTitle
00-00-80
COLOR_INACTIVECAPTION
InactiveTitle
80-80-80
COLOR_MENU
Menu
C0-C0-C0
COLOR_WINDOW
Window
FF-FF-FF
COLOR_WINDOWFRAME
WindowFrame
00-00-00
COLOR_MENUTEXT
MenuText
C0-C0-C0
COLOR_WINDOWTEXT
WindowText
00-00-00
COLOR_CAPTIONTEXT
TitleText
FF-FF-FF
COLOR_ACTIVEBORDER
ActiveBorder
C0-C0-C0
COLOR_INACTIVEBORDER
InactiveBorder
C0-C0-C0
COLOR_APPWORKSPACE
AppWorkspace
80-80-80
COLOR_HIGHLIGHT
Highlight
00-00-80
COLOR_HIGHLIGHTTEXT
HighlightText
FF-FF-FF
COLOR_BTNFACE
ButtonFace
C0-C0-C0
COLOR_BTNSHADOW
ButtonShadow
80-80-80
COLOR_GRAYTEXT
GrayText
80-80-80
COLOR_BTNTEXT
ButtonText
00-00-00
COLOR_INACTIVECAPTIONTEXT
InactiveTitleText
C0-C0-C0
COLOR_BTNHIGHLIGHT
ButtonHighlight
FF-FF-FF
COLOR_3DDKSHADOW
ButtonDkShadow
00-00-00
COLOR_3DLIGHT
ButtonLight
C0-C0-C0
COLOR_INFOTEXT
InfoText
00-00-00
COLOR_INFOBK
InfoWindow
FF-FF-FF
[no identifier; use value 25]
ButtonAlternateFace
B8-B4-B8
COLOR_HOTLIGHT
HotTrackingColor
00-00-FF
COLOR_GRADIENTACTIVECAPTION
GradientActiveTitle
00-00-80
COLOR_GRADIENTINACTIVECAPTION
GradientInactiveTitle
80-80-80
    我们定义窗口类时可以使用系统颜色如 COLOR_BTNFACE作为窗口客户区的背景颜色: wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
    在系统颜色标识符时加 1,这样做的目的是防止其值为NULL,没有任何其它目的。
    系统颜色改变时,可通过处理 WM_SYSCOLORCHANGE消息更新。
   
    按钮在绘制前会给父窗口发送一个 WM_CTLCOLORBTN消息,父窗口可以改变按钮的背景色和文本色。wParam参数是按钮的设备描述表句柄,lParam参数是按钮的窗口句柄,消息处理完后必须返回一个画刷句柄。但事实上只有自绘按钮才会响应这个消息。因此,这个消息没什么大用。
e)         自绘按钮( BS_OWNERDRAW
    使用 BS_OWNERDRAW风格建立的按钮会在需要重新绘制的任何时候向它的父窗口发送一个WM_DRAWITEM消息,包括以下的这些情况中:按钮被创建时,被按下或释放时,得到焦点或失去焦点时,以及按钮需要重新绘制的任何时候。lParam参数表示一个指向DRAWITEMSTRUCT结构的指针,该结构包含了绘制按钮必需的信息。
    在绘制自绘按钮后,务必保持其设备描述表的原有状态,务必销毁创建的所有GDI对象。
 
    有一种窗口类名为“ Static”的子窗口控件,它既不接收鼠标消息,又不接收键盘消息,也不向父窗口发送WM_COMMAND消息。
    鼠标在静态子窗口上移动或按下时,它捕获WM_NCHITTEST消息,并以HTTRANSPARENT值返回给Windows。这将使Windows向其父窗口发送WM_NCHITTEST消息。
 
       与按钮控件不同,滚动条子窗口控件不向父窗口发送 WM_COMMAND消息,而是像窗口滚动条那样发送WM_VSCROLL和WM_HSCROLL消息。在处理滚动消息时,您可以通过lParam参数来区分窗口滚动条与滚动条控件。对子窗口滚动条其值为0,对于滚动条控件其值为滚动条窗口句柄。对窗口滚动条和滚动条控件来说,wParam参数的高字组和低字组的含义相同。
    要想建立与窗口滚动条尺寸相同的滚动条控件,那么可以使用 GetSystemMetrics取得水平滚动条的高度:
    GetSystemMetrics (SM_CYHSCROLL);
或者垂直滚动条的宽度:
    GetSystemMetrics (SM_CXVSCROLL);
    对于窗口滚动条,可以使用同样的调用设置滚动条控件的范围和位置:
    SetScrollRange(hwndScroll,SB_CTL,iMin,iMax,bRedraw);
    SetScrollPos(hwndScroll,SB_CTL,iPos,bRedraw);
    SetScrollInfo(hwndScroll,SB_CTL,&si,bRedraw);
    如果捕获WM_CTLCOLORSCROLLBAR消息,那么可以在消息处理中返回画刷以改变滚动条本身颜色。
    滚动条控件的窗口过程是 Windows内部的。但是,将GWL_WNDPROC标识符作为参数调用GetWindowLong,就可以得到这个窗口过程的地址。另外,也可以调用SetWindowLong给该滚动条设置一个新的窗口过程,这个技术叫做“窗口子类化”。
    鼠标点击滚动条时,要想使滚动条获得输入焦点,调用 CreateWindow函数创建滚动条时必须包含WM_TABSTOP窗口风格。要想按下TAB键后转移输入焦点,必须通过“窗口子类化”实现。
   
    编辑框是最简单的预先定义窗口类;在另一方面,它又是最复杂的窗口类。使用类名“ edit”创建,功能是编辑文本。最常见的是单行文本框。
    窗口风格 ES_LEFT、ES_RIGHT或ES_CENTER分别可以将文本设置为左对齐、置右对齐或者居中。
    默认编辑框控件为单行,使用 ES_MULTILINE窗口风格可创建多行编辑框。多行编辑框文本缺省情况下自动换行,一旦设置了ES_AUTOHSCROLL风格,则必须按下Enter键换行。
    如果希望编辑框选中的文本失去输入焦点后依然被加亮,设置 ES_NOHIDESEL风格可以实现这一点。
    编辑框控件状态改变后,同样给父窗口过程发送 WM_COMMAND消息,参数含义和按钮控件基本相同。下表是编辑框控件发送通知消息包含的通知码:
EN_SETFOCUS
EN_KILLFOCUS
EN_CHANGE
EN_UPDATE
EN_ERRSPACE
EN_MAXTEXT
EN_HSCROLL
EN_VSCROLL
编辑框已经获得输入焦点
编辑框已经失去输入焦点
编辑框的内容将改变
编辑框的内容已经改变
编辑框执行已经超出中间
编辑框在插入时执行超出空间
编辑框的水平滚动条已经被按下
编辑框的垂直滚动条已经被按下
    SetWindowText和 GetWindowText函数分别用于设置和返回编辑框文本。
    SendMessage(hwndEdit,WM_CUT,0,0);       //剪切编辑框文本
    SendMessage(hwndEdit,WM_COPY,0,0);      //复制编辑框文本
    SendMessage(hwndEdit,WM_CLEAR,0,0);     //清空编辑框文本
    SendMessage(hwndEdit,WM_PASTE,0,0);     //将剪贴板文本粘贴到编辑框
    SendMessage(hwndEdit,EM_GETSEL,(WPARAM)&iStart,(LPARAM) &iEnd); //返回编辑框     选中文本首尾位置
    SendMessage(hwndEdit,EM_SETSEL,iStart,iEnd);    //选中部分编辑框文本
    …
    列表框是字符串的集合。列表框可以单选或多选。以“ list”窗口类创建的列表框控件缺省不向父窗口发送WM_COMMAND消息,必须包含LBS_NOTIFY窗口风格才行。如果希望对列表项排序,则应包含LBS_SORT窗口风格。缺省情况下列表框是单项选择的,如果希望多选,则应包含LBS_MULTIPLESEL风格。
    SendMessage(hwndList,LB_ADDSTRING 0,(LPARAM)szString); //追加一列表项
    SendMessage(hwndList,LB_INSERTSTRING,iIndex,(LPARAM)szString); //插入一列表     项
    SendMessage(hwndList,LB_DELETESTRING,iIndex,0); //删除一列表项
    SendMessage(hwndList,LB_RESETCONTENT,0,0);      //清空列表框内容
    SendMessage(hwndList,WM_SETREDRAW,FALSE,0);     //禁止重新绘制
    SendMessage(hwndList,WM_SETREDRAW,TRUE,0);      //允许重新绘制
    iCount = SendMessage (hwndList, LB_GETCOUNT,0,0);   //返回列表项数量
    SendMessage(hwndList,LB_SETCURSEL,iIndex,0);        //选中一个列表项
    iIndex = SendMessage(hwndList,LB_GETCURSEL,0,0);    //返回选中列表项索引
 
    下表是来自列表框控件通知消息中包含的通知码:
LBN_ERRSPACE
-2
LBN_SELCHANGE
1
LBN_DBLCLK
2
LBN_SELCANCEL
3
LBN_SETFOCUS
4
LBN_KILLFOCUS
5
    只有列表框风格包含 LBS_NOTIFY时,列表框控件才会向父窗口发送LBN_SELCHANGE和LBN_DBLCLK。
    LB_DIR,这是功能最强的列表框消息。它用文件目录列表填充列表框,甚至还可以包括子目录和磁盘驱动器。
    SendMessage(hwndList,LB_DIR,iAttr,(LPARAM)szFileSpec);
    iAttr参数是文件属性代码,其最低字节是文件属性代码 :
 
iAttr
属性
DDL_READWRITE
0x0000
普通文件
DDL_READONLY
0x0001
只读文件
DDL_HIDDEN
0x0002
隐藏文件
DDL_SYSTEM
0x0004
系统文件
DDL_DIRECTORY
0x0010
子目录
DDL_ARCHIVE
0x0020
有归档位集的文件
    高字节提供了一些对所要求项目的附加控制:
 
iAttr
属性
DDL_DRIVES
0x4000
包括驱动器的字母
DDL_EXCLUSIVE
0x8000
互斥搜索
    LB_DIR消息的 iAttr值为DDL_READWRITE时,列表框列出普通文件、只读文件和有归档位集的文件;值为DDL_DIRECTORY时,列表框除了列出上述文件之外,还列出子目录;值为DDL_DRIVES | DDL_DIRECTORY时,那么列表将扩展到驱动器。
    将 iAttr的最高位置位就可以只列出符合条件的文件,而不包括其它文件。
    lParam参数是指向文件指定字符串如「 *.*」的指针,这个文件指定字符串不影响列表框中的子目录。
 
 
 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值