不使用MFC, 为何dialog无法响应WM_KEYDOWN消息

boby 2003-02-05 05:48:03
rt
...全文
192 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
bill_zzx 2003-02-21
  • 打赏
  • 举报
回复
怎么解决了?请告知
boby 2003-02-12
  • 打赏
  • 举报
回复
自己解决了
kingcom_xu 2003-02-06
  • 打赏
  • 举报
回复
Q117563


--------------------------------------------------------------------------------
The information in this article applies to:

The Microsoft Foundation Classes (MFC), used with:
Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5, 1.51, 1.52
Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 4.0
Microsoft Visual C++ 32-bit Edition, versions 2.0, 2.1, 4.0

--------------------------------------------------------------------------------


SUMMARY
Certain Windows messages are difficult to trap in a dialog box because they are either processed by the Windows internal dialog procedure or sent to the control instead of the dialog box. There are several ways to do this, but they usually involve subclassing all the controls in the dialog box or using a Windows hook function. The method described in this article uses the predefined overridable MFC hook function ProcessMessageFilter() to capture these messages. The idea is to override the MFC preinstalled hook function, ProcessMessageFilter(), to trap the messages before they get to the dialog box.



MORE INFORMATION
The following steps are the required to implement the hook function. The SCRIBBLE sample was used as the base for the steps. In Visual C++ 32-bit Edition, version 4.0, use SCRIBBLE sample STEP3.

In this example, the steps outlined below trap WM_KEYDOWN for a specific dialog box:



Add a member variable to your CWinApp-derived class to hold the handle to the dialog box for which you want to trap the messages. You need to know the handle because ProcessMessageFilter is receiving messages for the entire application, while you only want a small selection of those messages:

SCRIBBLE.H

<Inside CScribbleApp class>

public:
HWND m_hwndDialog;

SCRIBBLE.CPP

<Inside CScribbleApp::InitInstance>

m_hwndDialog = NULL;
NOTE: Because this message filter applies to the entire application, there may be a performance hit when you use this method.


Override CWinApp::ProcessMessageFilter in your CWinApp-derived class. CWinApp::ProcessMessageFilter is a virtual function of CWinApp, so all you need to do is put a declaration in the header file and an implementation in the source file.

SCRIBBLE.H

public:
virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);

SCRIBBLE.CPP

BOOL CScribbleApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
// Check to make sure CPenWidthsDlg is up
if (m_hwndDialog != NULL)
{
if ((lpMsg->hwnd == m_hwndDialog) ||
::IsChild(m_hwndDialog, lpMsg->hwnd))
// Use ::IsChild to get messages that may be going
// to the dialog's controls. In the case of
// WM_KEYDOWN this is required.
{
if (lpMsg->message == WM_KEYDOWN)
TRACE("Got WM_KEYDOWN\n");
}
}
// Default processing of the message.
return CWinApp::ProcessMessageFilter(code, lpMsg);
}
For more information on overriding ProcessMessageFilter, please see the MFC online Help.


Add initialization code for the dialog handle member variable in our OnInitDialog for the desired dialog box. You also have to add exit code to reset the member variable after the dialog box closes:

PENDLG.H

protected:
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();

PENDLG.CPP

<Add to Message Map>
ON_WM_DESTROY()

BOOL CPenWidthsDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Use AfxGetApp() to get pointer to CWinApp-derived
// object; then cast the pointer to our type and assign
((CScribbleApp *)AfxGetApp())->m_hwndDialog = m_hWnd;

return TRUE; // Return TRUE
// unless you set the focus to a control.
}

void CPenWidthsDlg::OnDestroy()
{
CDialog::OnDestroy();

// Use AfxGetApp() to get pointer to CWinApp-derived
// object; then cast the pointer to our type and assign
((CScribbleApp *)AfxGetApp())->m_hwndDialog = NULL;

}



Once these steps are completed, you can trap any message intended for the CPenWidthsDlg or any of its children (such as edit controls, combo boxes, and radio buttons)

If this method is unacceptable because of the application-wide nature of the message filter, please see the following article in the Microsoft Knowledge Base:
Q72219 Context-Sensitive Help in a Dialog Box Through F1
This article explains how to set a hook function for a specific dialog and how to remove the hook after the dialog box has terminated. That method requires more Windows programming knowledge.

Additional query words: kbinf 1.00 1.50 2.00 2.10 2.50 3.00 3.10 4.00 key keystroke

Keywords : kbDlg kbHook kbKeyIn kbMFC kbVC100 kbVC150 kbVC200 kbVC400 kbArchitecture
Issue type : kbhowto
Technology : kbAudDeveloper kbMFC

kingcom_xu 2003-02-06
  • 打赏
  • 举报
回复
我想用hook是比较好的做法了...
MFC中也是用hook实现的..
showmetheway 2003-02-06
  • 打赏
  • 举报
回复
既然对话框接受不到WM_KEYDOWM,那就应该在对话框的任何一个控件的窗口函数中加才对吧。。
akiy 2003-02-06
  • 打赏
  • 举报
回复
to showmetheway(雪儿甜心)
if(pMsg->message==WM_KEYDOWN)
{//现在就得到了该事件下面可以做相应处理了
pMsg->wparam就是被按下的键值

}
akiy 2003-02-06
  • 打赏
  • 举报
回复
to : hnyyy(前进)
谢谢呢!!:)
boby 2003-02-06
  • 打赏
  • 举报
回复
如何发消息,我的窗口处理函数如下:
DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
...
switch(msg)
{
case WM_...
case WM_...
case WM_...
}
}
请问SendMessage(...)应该加在何处才能响应WM_KEYDOWN
showmetheway 2003-02-06
  • 打赏
  • 举报
回复
我也想知道。。。
wwjokwang 2003-02-06
  • 打赏
  • 举报
回复
向对话框窗口发送消息
明天去抢劫 2003-02-06
  • 打赏
  • 举报
回复
试试向对话框窗口SendMessage(WM_KEYDOWN)
看它是不是响应了
boby 2003-02-06
  • 打赏
  • 举报
回复
但是PreTranslateMessage()是基于MFC的
showmetheway 2003-02-06
  • 打赏
  • 举报
回复
我也只知道试不想应,经常用pretranslatemessage拦截
不知道为什么,up
///////////////////////////////////
请问在这里pretranslatemessage该如何调用才能拦截WM_KEYDOWN消息?准确的说放在程序的什么位置。。
ficher 2003-02-05
  • 打赏
  • 举报
回复
对话框有自己的消息循环函数,所以自己加的时候注意一下位置,不要放到父窗口的消息循环函数
showmetheway 2003-02-05
  • 打赏
  • 举报
回复
对话框始终不具有焦点
///////////////////
可以通过setfocus函数强制使它具有焦点吗?
boby 2003-02-05
  • 打赏
  • 举报
回复
那么该如何响应?
hnyyy 2003-02-05
  • 打赏
  • 举报
回复
应该可以这样解释:
对话框始终不具有焦点,因此接受消息的是它上面具有焦点的控件。
通常是用pretranslatemessage。


akiy(宏) 兄已上星了,恭贺!!
smilingdeng 2003-02-05
  • 打赏
  • 举报
回复
自己手动添加呀
boby 2003-02-05
  • 打赏
  • 举报
回复
是的,没有使用MFC,我直接使用对话框消息处理函数,但无法响应WM_KEYDOWN消息
kingcom_xu 2003-02-05
  • 打赏
  • 举报
回复
不使用MFC?
加载更多回复(1)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧