windows程序设计学习笔记-子窗口控件

9.子窗口控件

焦点相关

鼠标单击消息:
发送给鼠标位置所在窗口(有子不发父)

鼠标单击子窗口,若父窗口不是活动窗口,通过给父窗口设置焦点让父窗口成为活动窗口

窗口有隐藏变显示时,父窗口收到设置焦点消息

子窗口和父窗口焦点的关系(见7-Checker4)

默认处理的鼠标消息不会改变父子窗口间的焦点关系

父子窗口间的焦点转移或子窗口与子窗口间的焦点转移只能通过显示的SetFocus方法来实现。

空白的窗口有焦点但是外观上看不出来。
通过我们看到单击子窗口如按钮等,按钮就有了焦点,这其实是因为按钮的默认类中在处理左键时,加上了设置焦点的操作。

hwndParent = GetParent(hwnd);
子窗口给父窗口发消息:
SendMessage(hwndParent, message, wParam, lParam);// message >= WM_USER

子窗口控件:
子窗口状态发生改变时,子窗口处理鼠标和键盘的消息,并且通知父窗口。
既可以创建自己的子窗口控件,也可以利用一些预定义的窗口类和窗口过程,产生标准的子窗口控件。

程序的父窗口发送消息给子窗口控件,子窗口控件将消息发送回父窗口过程。

常用的控件种类有:
按钮,复选框,编辑框, 列表框,组合框,文本字符串,滚动条。

使用预定义控件时,不需要注册相应子窗口的类,这些类已经存在于windows中并已经有预定义的名称。Windows包含相应的窗口过程,在这些窗口类的基础上,窗口过程处理送往子窗口的消息。

在对话框中使用窗口子控件时,对话框管理器在你的程序和控件之间增加了一个隔离层。这个对话框管理器帮你做了一些处理工作。
在窗口表面直接使用子窗口时,没有这个隔离层。

获取实例句柄:
1.在WM_CREATE中
((LPCREATESTRUCT)lParam)->hInstance
2.
GetWindowLong(hwnd, GWL_HINSTANCE);
3.
在WinMain中,hInst = hInstance;

程序终止时,Windows在销毁父窗口的同时销毁这些子窗口。

9.1.按钮

对于按钮,在鼠标单击一个按钮时,子窗口控件发送WM_COMMAND给父窗口。
WM_COMMAND:
LOWORD(wParam):子窗口ID
HIWORD(wParam):通知码
lParam:子窗口句柄

按钮通知码标识符:
BN_CLICKED

// 有条件发送
BN_PAINT
BN_HILITE或BN_PUSHED
BN_UNHILITE或BN_UNPUSHED
BN_DISABLE
BN_DOUBLECLICKED或BN_DBLCLK

// 仅当按钮样式含BS_NOTIFY时发送
BN_SETFOCUS
BN_KILLFOCUS

8个专用于按钮的消息:
// 获取或设置复选框和单选按钮的状态
BM_GETCHECK/SETCHECK
BM_GETSTATE/SETSTATE
// 允许创建按钮后改变其样式
BM_SETSTYLE
BM_CLICK
BM_GETIMAGE/SETIMAGE

9.1.1.按钮

有两种类型的按键按钮控件,窗口样式分别为BS_PUSHBUTTON,BS_DEFPUSHBUTTON。
在被用于设计对话框时,两类控件的功能是完全不同的。但被用作子窗口控件时,两类按钮的表现基本相同。

9.1.2.复选框

开关切换,多个选择
常见的两类样式:
BS_CHECKBOX,BS_AUTOCHECKBOX
对于BS_CHECKBOX按钮控件选择标记的切换由父窗口通过向按钮控件发消息【BM_SETCHECK】来控制。对于BS_AUTOCHECKBOX,按钮控件本身负责切换选定和取消标记。

另外两个样式:BS_3STATE,BS_AUTO3STATE。这些显示可显示三种状态,选中,未选中,灰色【表示选择是不确定或无关紧要的】

9.1.3.单选按钮

单选按钮常用样式:
BS_RADIOBUTTON,BS_AUTORADIOBUTTON【只用于对话框】
父控件收到来自单选按钮的WM_COMMAND时,应向其发一条wParam为1的BM_SETCHECK来选中,对组内其他单选按钮发一个wParam为0的BM_SETCHECK。

9.1.4.组合框

BS_GROUPBOX。
既不处理鼠标或键盘输入也不发送WM_COMMAND到父窗口。

对于以上四类按钮:
改变/获取窗口标题栏文本【对于按钮就是在按钮中显示的文本】:SetWindowText/GetWindowText

要接受鼠标和键盘输入,子窗口必须是可见的并且是启用的。
ShowWindow:来显示或隐藏窗口
IsWindowVisible:判断窗口是否可见
EnableWindow:来启用或禁用窗口
IsWindowEnable:判断窗口是否被启用

按钮有焦点时,用虚线框标识。
Windows把输入焦点从一个窗口切换到另一个窗口时,首先向要失去焦点的窗口发WM_KILLFOCUS。
WM_KILLFOCUS:
wParam:失去输入焦点窗口的句柄。

按钮有焦点时,键盘消息都发给了有焦点的按钮,按钮只处理空格键,导致此时按Tab键无反应,无法实现在多个按钮子窗口控件间切换。。【按钮作为对话框子控件因为中间层存在,不存在此问题】

系统颜色
SetSysColors/GetSysColor:获取和设置当前窗口的系统颜色。

COLOR_BTNFACE用于按键按钮的主表面颜色和其他按钮的背景颜色。
COLOR_BTNSHADOW用在按钮右侧,底部,复选框方块内部,单选按钮圆圈内来表示阴影。
COLOR_BTNTEXT:按键按钮文本色
COLOR_WINDOWTEXT:其他控件的文本颜色

wndclass.hbrBackground//可以直接用上面颜色宏来为其赋值。

设备环境中默认的文本背景是白色,文本是黑色。可以对设备环境用
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE))
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT))

系统颜色改变时,windows向所有正在运行程序发WM_SYSCOLORCHANGE

// 以下只对按键按钮和自绘按钮
在子窗口即将重绘其客户区时,按钮控件发送WM_CTLCOLORBTN给父窗口。父窗口可以在处理此消息时,改变子窗口背景色。
WM_CTLCOLORBTN:
wParam:按钮的设备环境句柄
lParam:按钮的窗口句柄

在处理WM_CTLCOLORBTN时,可以:
SetTextColor
SetBkColor
返回子窗口的画刷句柄//子窗口使用此画刷来着色背景

对于BS_OWNERDRAW:
lParam:指向DRAWITEMSTRUCT类型结构的指针。这个结构存有必要的信息来帮助程序绘制按钮【对于自绘列表框和菜单项也是如此】。
这个结构几个重要字段:
hDC:按钮设备环境
rcItem:按钮尺寸
CtlID:控件ID
itemState:是否按下或有输入焦点ODS_SELECTED【按下标志位】,ODS_FOCUS【焦点标志位】

9.2.静态类

此类窗口不接受鼠标或键盘输入,不向其父窗口发送WM_COMMAND消息。

SS_BLACKRECT,SS_GRAYRECT,SS_WHITERECT
SS_BLACKFRAME,SS_GRAYFRAME,SS_WHITEFRAME
SS_ETCHEDHORZ,SS_ETCHEDVERT,SS_ETCHEDFRAME
文本对齐:
SS_LEFT,SS_RIGHT, SS_CENTER

9.3.滚动条

滚动条控件,是子窗口,可出现在父窗口客户区的任何地方。

滚动条控件不发送WM_COMMAND到父窗口,类似窗口滚动条,他们向父窗口发送WM_VSCROLL,WM_HSCROLL。
WM_VSCROLL/WM_HSCROLL:
lParam:0,说明是窗口滚动条。或滚动条控件句柄

GetSystemMetrics(SM_CYHSCROLL):水平滚动条高度
GetSystemMetrics(SM_CXVSCROLL)
:垂直滚动条高度

SBS_LEFTALIGN, SBS_RIGHTALIGN, SBS_TOPALIGN, SBS_BOTTOMALIGN
上面这些只针对对话框中的滚动条。

窗口子类技术:
OldWndProc = (WNDPROC) SetWindowLong (hwnd,
GWL_WNDPROC, (LONG) NewProc) ;
使本来发给窗口过程的消息现在发给NewProc,这个窗口过程。
LRESULT CALLBACK NewProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
// 在其中处理了必要的消息后,可以通过 return CallWindowProc (OldWndProc, hwnd, message, wParam, lParam) ;把其他消息传给原窗口过程处理。
在使用预定义窗口类时,希望对某些消息做特殊处理时十分有效。
SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG)hBrush)

9.4.编辑类

编辑控件向其父窗口过程发送WM_COMMAND消息
LOWORD(wParam):子窗口ID
HIWORD(wParam):通知码
lParam:窗口句柄

常见通知码举例:
EN_SETFOCUS:得焦点
EN_KILLFOCUS:
EN_CHANGE:内容将变化
EN_UPDATE:内容已变化
EN_ERRSPACE:没有空间了
EN_MAXTEXT:没有空间完成插入了
EN_HSCROLL:水平滚动条被单击了
EN_VSCROLL:垂直滚动条被单击了

SetWindowText:把文本插入编辑框
GetWindowText/GetWindowTextLength:获取文本

给编辑控件发消息:
WM_CUT
WM_COPY
WM_CLEAR
WM_PASTE

EM_GETSELEM_SETSEL/:获取/设置选择文本起始位置
EM_REPLACESEL:文本替换
EM_GETLINECOUNT
EM_LINEINDEX:从起点到某行的位移量
EM_LINELENGTH:得行长
EM_GETLINE:复制某行到缓冲区

9.5.列表框

将一批文本字符串显示在一个具有滚动功能的方框中的控件。
列表框控件几乎总包含LBS_NOTIFY样式,来使父窗口收到从列表框发来的WM_COMMAND消息。如果想让列表框项目进行排序,可使用样式LBS_SORT。
默认下列表框是单选的。可用LBS_MULTIPLESEL设置多选。
默认下列表框中添加了新项时,列表框自动更新,可用LBS_NOREDRAW来阻止。可用WM_SETREDRAW来暂时阻止。
WS_BORDER:边框效果
WS_VSCROLL/WS_HSCROLL:添加水平或垂直滚动条
WS_SIZEBOX:允许调整大小
WS_CAPTION:允许移动

往列表框SendMessage成功返回,LB_OKAY
向列表框添加字符串:
LB_ADDSTRING
对LBS_SORT样式:
SendMessage(hwndList, LB_ADDSTRING, 0 , (LPARAM)szString)
LB_INSERTSTRING
SendMessage(hwndList, Lb_INSERTSTRING, iIndex, (LPARAM)szString)// 下标从0计
LB_DELETESTRING
LB_RESETCONTENT:清除所有
WM_SETREDRAW:关闭/打开重绘标志
SendMessage(hwndList, WM_SETREDRAW, FALSE/TRUE, 0)

LB_GETCOUNT:获取项目数
LB_GETTEXTLEN:获取某项字符串长度
LB_GETTEXT:把某项复制到缓冲区。缓冲区要大的能包含字符串和结束符

对单选列表框:
LB_SETCURSEL:设置默认选中项
LB_SELECTSTRING:寻找首个与搜索字符串匹配的项目,没找到匹配返回LB_ERR
LB_GETCURSEL:获取当前选择项,没项目被选中,返回LB_ERR

对多选框:
LB_SETSEL:设置某项选中状态
SendMessage(hwndList, LB_SETSEL, 0/1, iIndex)
LB_GETSEL:获取某项选中状态
iSelect = SendMessage(hwndList, LB_GETSEL, iIndex, 0)//选中返回非0值,没选中,返回0

当一个列表框具有输入焦点时,光标移动键,字符键,空格键,可用于从中选择项目。

对话框相关

HWND WINAPI CreateDialogParam(
In_opt HINSTANCE hInstance,
In LPCTSTR lpTemplateName,
In_opt HWND hWndParent,
In_opt DLGPROC lpDialogFunc,
In LPARAM dwInitParam
);

// 无参数传递版本
HWND WINAPI CreateDialog(
In_opt HINSTANCE hInstance,
In LPCTSTR lpTemplate,
In_opt HWND hWndParent,
In_opt DLGPROC lpDialogFunc
);

//

创建一个非模态对话框从对话框模板资源。显示对话框前,函数传递一个应用定义值给对话框处理过程的WM_INITDIALOG
消息的lParam参数。应用可使用此值来初始化对话框。
hInstanc:一个句柄指向包含对话框模板的模块。为NULL时,模板用当前可执行程序。
lpTemplateName:
可以是一个字符串指定对话框模板的名字 或 一个整数指定对话框资源标识。
如果参数指定资源标识,高位须是0,低位包含标识。
可以 MAKEINTRESOURCE创建此值。
hWndParent:句柄指向拥有对话框的窗口
lpDialogFunc :指针指向对话框处理过程
dwInitParam:传递给对话框处理过程 WM_INITDIALOG消息的lParam参数的值。

返回值:
成功,对话框句柄。
失败,NULL

要支持键盘导航和其他对话框功能,对话框的消息循环需要调用 IsDialogMessage.
在主程序的消息循环里要判断对话框句柄不存在或消息不是对话框的消息才能让消息进入主程序中的翻译和派发

INT_PTR CALLBACK DialogProc(
In HWND hwndDlg,
In UINT uMsg,
In WPARAM wParam,
In LPARAM lParam
);

应用定义的回调函数。在 CreateDialog 和 DialogBox 此类函数中使用。
处理发给模态或非模态对话框的消息。

hwndDlg:句柄指向对话框。
uMsg :消息
wParam:消息参数
lParam:消息参数

返回值:
典型地,如果对话框处理过程处理了消息,返回TRUE。否则,FALSE。
如果对话框处理过程返回FALSE,对话框管理器执行默认对话框操作来回复此消息。
如果对话框处理过程处理一个消息,此消息需要一个特定返回值。对话框处理过程
应该设置想要的返回值通过调用SetWindowLong在返回TRUE之前。

以下消息对上面陈述的规则来说是例外。咨询文档来获取指定消息返回值的具体语义。
WM_CHARTOITEM
WM_COMPAREITEM
WM_CTLCOLORBTN
WM_CTLCOLORDLG
WM_CTLCOLOREDIT
WM_CTLCOLORLISTBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC
WM_INITDIALOG
WM_QUERYDRAGICON
WM_VKEYTOITEM

INT_PTR WINAPI DialogBox(
In_opt HINSTANCE hInstance,
In LPCTSTR lpTemplate,
In_opt HWND hWndParent,
In_opt DLGPROC lpDialogFunc
);

用对话框模板资源创建一个模态对话框。
DialogBox不返回控制,直到指定的回调函数通过调用EndDialog来终止模态对话框。

hInstance:指向包含对话框模板模块的句柄。为NULL时,模块为当前可执行程序。
lpTemplate :
可以是一个字符串指定对话框模板的名字 或 一个整数指定对话框资源标识。
如果参数指定资源标识,高位须是0,低位包含标识。
可以 MAKEINTRESOURCE创建此值。
hWndParent :句柄指向拥有对话框的窗口
lpDialogFunc :指针指向对话框处理过程

返回值:
成功, 返回值是 在调用EndDialog来终止对话框中的nResult参数。
失败,
若由hWndParent无效导致,返回值为0.
其他原因导致的失败,返回-1.

函数显示对话框,无论对话框模板是否指定了WS_VISIBLE。让拥有其窗口 无效,开始它自己的消息循环来为对话框自己获取和分发消息。

当对话框处理过程调用EndDialog,DialogBox销毁对话框,结束消息循环,使能拥有窗口(如窗口之前为使能的话),返回EndDialog中的nResult参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值