当程序中出现非模态对话框的时候,消息循环必须写成
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hDlg1,&msg))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//}
}
} return msg.wParam;
}
查了MSDN,知道了:
when isdialogmessage processes a message,it checks for keyboard message and converts them into selections for
the corresponding dialog box.
IsDialogMessage是检查对话框上的键盘消息的,我测试了一下:
在键盘上放置3个按钮,OK,BUTTON1,BUTTON2,缺省按钮是OK,三个按钮都有制表符TAB,运行的时候测试结果汇报如下:
当按下键盘上的TAB键焦点会在三个按钮之间进行切换,按下回车或者空格就会触发OK按钮(缺省按钮嘛)来关闭对话框。当把IsDialogMessage注释掉之后,测试汇报:
此时运行默认焦点还是在OK上(缺省按钮),当按下TAB键时没有任何反应(证明了此函数确实是管理对话框的按键消息的)
当按下回车的时候也没有任何反应,但是,但是,特此强调的是:当按下空格键的时候,会触发消息关闭对话框。问题来了:既然IsDialogMessage是管理键盘消息的,那按下空格跟按下回车,TAB不都是按键消息(WM_KEYDOWN)吗,为何,回车,TAB都没反应,空格却有反应呢?
特此到论坛求助,欢迎回答,先说谢谢!!!
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hDlg1,&msg))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//}
}
} return msg.wParam;
}
查了MSDN,知道了:
when isdialogmessage processes a message,it checks for keyboard message and converts them into selections for
the corresponding dialog box.
IsDialogMessage是检查对话框上的键盘消息的,我测试了一下:
在键盘上放置3个按钮,OK,BUTTON1,BUTTON2,缺省按钮是OK,三个按钮都有制表符TAB,运行的时候测试结果汇报如下:
当按下键盘上的TAB键焦点会在三个按钮之间进行切换,按下回车或者空格就会触发OK按钮(缺省按钮嘛)来关闭对话框。当把IsDialogMessage注释掉之后,测试汇报:
此时运行默认焦点还是在OK上(缺省按钮),当按下TAB键时没有任何反应(证明了此函数确实是管理对话框的按键消息的)
当按下回车的时候也没有任何反应,但是,但是,特此强调的是:当按下空格键的时候,会触发消息关闭对话框。问题来了:既然IsDialogMessage是管理键盘消息的,那按下空格跟按下回车,TAB不都是按键消息(WM_KEYDOWN)吗,为何,回车,TAB都没反应,空格却有反应呢?
特此到论坛求助,欢迎回答,先说谢谢!!!
感谢回答,貌似跟我的问题对不上吧,还请仔细看下我的问题。
我在对话框的窗口过程函数中加入了
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
DestroyWindow(hDlg1);
return TRUE;
}
break;
case WM_KEYDOWN:
MessageBox(hDlg,TEXT("A"),TEXT("B"),0);
return 0;
case WM_CLOSE:
DestroyWindow(hDlg1);
hDlg1=0;
return TRUE;
}
return FALSE;
}case WM_KEYDOWN:测试这个消息压根就没响应,这到底是咋么回事呢?
那TAB键的消息不也是WM_KEYDOWN吗?咋么。。望指点
你测试这个时有没有IsDialogMessage
你空格咋么还会响应?按下空格不也属于WM_KEYDOWN吗?如何解释?
有根没有两个情况都测试了,都没响应WM_KEYDOWN消息。
莫非对话框就不响应WM_KEYDOWN消息?只响应WM_COMMAND消息。
迷迷糊糊的,没理解明白这个过程。
翻译后的TAB不也是按键消息吗,连WM_KEYDOWN都不处理了,那肯定对TAB也没用了啊,WM_KEYDOWN包含TAB键的。请问如何解释。
所以如果你按了tab
在WM_KEYDOWN到达控件的窗口过程前,ISDIALOGMESSAGE有机会处理它
IsDialogMessage会像对话框的可能接受这个WM_KEYDOWN控件发送WM_GETDLGCODE消息来知道这些控件是否需要处理tab如果没有控件处理tab,则tab可以被用作选择控件的按键,IsDialogMessage就会改变焦点窗口
这句话是什么意思,求解释,消息分发第一次听说,谢谢。
消息有两种,一种是队列消息,一种是非队列消息
PostMessage,按键,产生队列消息,SendMessage,CreateWindow产生非队列消息
GetMessage在执行的过程中,会分发所有的非队列消息(调用对应的窗口过程),处理完非队列消息后,如果还有队列消息,就根据队列的顺序取出一个返回,否则继续等消息队列消息一般会由TranslateMessage转换,然后由DispatchMessage分发至窗口过程IsDialogMessage处理的是队列消息,只有队列消息才能被GetMessage和PeekMessage取回
仍然有个问题:
ISDIALOGMESSAGE是判断一个消息是否是对话框消息的
换句话说:如何判断一个消息是否是对话框消息?
按下一个TAB键盘,会触发WM_KEYDOWN,这个WM_KEYDOWN消息应该是当前拥有焦点的控件的才对吧,也就是说这个消息根本不是对话框的消息,即:ISDIALOGMESSAGE没有拦截到此消息,因为当前有焦点的不是对话框,而是对话框上的控件。不知道我这么理解对不对?
我的意思是:WM_KEYDOWN不也可以是某个对话框上的控件上触发的吗,为何就说是对话框消息?
这点不明白
MSDN都说IsDialogMessage处理TAB键了,当然是返回1了,怎么你还说TAB键被OK按钮自己进行了处理
case WM_GETDLGCODE:
OutputDebugStringA("aaa");
return 2;这里2代表我要处理tab键
这样如果焦点在IDOK,你按tab就不会有切换控件的功能,因为可能处理消息的控件说自己要处理这个消息IsDialogMessage不会像所有控件发送WM_GETDLGCODE,只是向有可能会处理消息(IsDialogMesage第二参数指定的)控件发送WM_GETDLGCODE,这样的控件通常是焦点窗口
IsDialogMessage sends WM_GETDLGCODE messages to the dialog box procedure to determine which keys should be processed
经过测试确实是应该写在控件的窗口过程函数中。
我说一下IsDialogMessage的返回值情况你看对吗比如这里我在BTNWNDPROC中写入了WM_getdlgcode,并且返回了DLGC_WANTTAB9(也就是2)表示我这个控件自己会处理这个按键消息,不需要您对话框操心,因此这个消息就不在属于对话框消息了,即:IsDialogMessage返回0。分析的没错吧。
一般情况下给对话框控件的都是对话框消息,IsDialogMessage内部也有
TranslateMessage(&msg);
DispatchMessage(&msg);
来分发消息
多谢,对了,顺便说下用dialogbox创建的模态对话框是如何处理的呢?是不是它内部全部都处理好了?
模态对话框的消息跟非模态对话框的消息处理有什么区别吗,这个我也知道一点,不是很清楚,麻烦你在这里说说吧。
然后内部有像while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hDlg1,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
//}
}
} return msg.wParam;
} 这样的消息循环,都是差不多的