11、对话框

1、对话框

对话框是一种特殊的窗口,通常包含各种子窗口控件。特殊的地方在于,它的窗口过程属于windows,程序员拥有的被称作"对话框过程",windows窗口过程内部会调用对话框过程,把一些消息交给程序员处理。

2、设计对话框

可以在资源管理界面中设计对话框,把各种子窗口控件布局在对话框中。需要注意的是,对话框设计中使用的坐标值和尺寸并不是以像素为单位,它们的大小基于对话框当前使用的字体大小:

  • x坐标和宽度以字符平均宽度的1/4为单位
  • y坐标和高度以字符高度的1/8为单位
3、对话框过程

对话框过程不是真正的窗口过程,但对于许多消息窗口过程会调用对话框过程。对话框过程声明如下:

INT_PTR (CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM);

通常,如果对话框过程处理了消息,应该返回TRUE,否则返回FALSE。如果对话框过程返回FALSE,窗口过程会对消息进行默认处理。所以,对话框过程不应该调用DefWindowProc,应该把默认操作交给窗口过程负责。

但是,也有一些例外情况。比如WM_INITDIALOG消息,如果对话框过程返回TRUE,窗口过程会把焦点设置在wParam参数指定的控件。如果需要自己设定获取焦点的控件,则应该返回FALSE

对话框过程最常处理的是子窗口控件的WM_COMMAND消息。

4、模态对话框和非模态对话框

当显示一个模态对话框时,用户无法切换到该程序的其他窗口,只能对模态对话框进行输入,可以使用DialogBox函数创建显示模态对话框。DialogBox会阻塞当前线程,直到对话框被关闭。可以使用EndDialog来关闭对话框,其第二个参数作为DialogBox的返回值。模态对话框有内建的消息循环,不使用程序的消息循环。如果想传递额外参数到模态对话框的对话框过程,可以使用DialogBoxParam,其最后一个传参作为WM_INITDIALOGlParam参数传递到对话框过程。

当显示一个非模态对话框时,用户可以切换到该程序的其他窗口,可以使用CreateDialog函数创建非模态对话框,CreateDialog会立即返回,不会阻塞线程。当不在需要对话框时,使用DestroyWindow来关闭非模态对话框。如果想传递额外参数到非模态对话框的对话框过程,可以使用CreateDialogParam,其最后一个传参作为WM_INITDIALOGlParam参数传递到对话框过程。

5、模态对话框键盘接口

模态对话框提供了一些默认的键盘接口,比如按下tab键时把输入焦点切换到下一个控件,按下方向键时在同组控件内移动输入焦点等。非模态对话框没有这些键盘接口,但只要修改消息循环代码段,就可以为非模态对话框提供相同的键盘接口:

while (GetMessage(&msg, NULL, 0, 0))
{
	if (!IsDialogMessage(hwnd, &msg))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}

关键在于IsDialogMessage函数,IsDialogMessage通过向子窗口控件发送WM_GETDLGCODE消息来判断是否处理当前按键消息。如果子窗口控件没有处理当前按键消息,IsDialogMessage就提供默认功能,并返回0,消息循环不应该再把该消息发送出去,否则,IsDialogMessage不处理按键消息,返回1,消息循环把消息发送出去让对应控件处理消息。

子窗口控件会响应WM_GETDLGCODE消息,它的返回值反应了子窗口控件会处理的按键消息。比如edit控件处理WM_GETDLGCODE消息的返回值带有DLGC_WANTCHAR,也就是edit控件会处理字符消息。可以利用子类化和IsDialogMessage,让edit控件无法处理字符消息:

// 对话框过程中子类化edit控件
case WM_INITDIALOG:
		SetWindowSubclass(GetDlgItem(hDlg, IDC_EDIT1), SubClassProc, 0, 0);
		break;

LRESULT CALLBACK SubClassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uId, DWORD_PTR dwData)
{
	switch (message)
	{
	case WM_GETDLGCODE:
		return DefSubclassProc(hwnd, message, wParam, lParam)  & !DLGC_WANTCHARS;
	}

	return DefSubclassProc(hwnd, message, wParam, lParam);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值