孙鑫VC++深入详解:Lesson8 Part3---如何让对话框捕获WM_KEYDOWN消息?

来源:互联网 发布:软件测试方案内容 编辑:程序博客网 时间:2024/06/02 05:31

因为对话框程序中,某些特点的消息,如按键消息被Windows内部的对话框过程处理了,即基类完成了或者被发送给子控件处理,所以在对话框类中就不能捕获到按键消息


解决办法:在子类中覆盖基类的特定消息过滤响应函数.

在MFC中,用虚函数ProcessMessageFilter()来过滤或者响应菜单和对话框的特定Windows消息.

在子类中覆盖它,接管消息响应.

本例中,在CWinSunApp类中增加虚函数 ProcessMessageFilter

[cpp] view plaincopy
  1. //覆盖基类的虚函数,接管消息  
  2. BOOL CWinSunApp::ProcessMessageFilter(int code, LPMSG lpMsg)   
  3. {  
  4.     // TODO: Add your specialized code here and/or call the base class  
  5.       
  6.     if(m_hwndDlg!=NULL)  
  7.     {  
  8.         if(lpMsg->message==WM_KEYDOWN) //if(lpMsg->message==WM_KEYUP/WM_CHAR)   
  9. //if(lpMsg->message==WM_KEYDOWN&&lpMsg->wParam=='1'||lpMsg->wParam==VK_RETURN)
  10.             AfxMessageBox("捕获WM_KEYDOWN成功!");  //keybd_event(VK_TAB,0,0,0);
  11.     }  
  12.       
  13.     return CWinApp::ProcessMessageFilter(code, lpMsg);  
  14. }  

WinSunApp.h

[cpp] view plaincopy
  1. // WinSun.h : main header file for the WINSUN application  
  2. //  
  3.   
  4. #if !defined(AFX_WINSUN_H__025D80ED_531B_42C3_8C9F_1EB3093C7BC9__INCLUDED_)  
  5. #define AFX_WINSUN_H__025D80ED_531B_42C3_8C9F_1EB3093C7BC9__INCLUDED_  
  6.   
  7. #if _MSC_VER > 1000  
  8. #pragma once  
  9. #endif // _MSC_VER > 1000  
  10.   
  11. #ifndef __AFXWIN_H__  
  12.     #error include 'stdafx.h' before including this file for PCH  
  13. #endif  
  14.   
  15. #include "resource.h"       // main symbols  
  16.   
  17. /////////////////////////////////////////////////////////////////////////////  
  18. // CWinSunApp:  
  19. // See WinSun.cpp for the implementation of this class  
  20. //  
  21.   
  22. class CWinSunApp : public CWinApp  
  23. {  
  24. public:  
  25.     HWND m_hwndDlg;  
  26.     CWinSunApp();  
  27.   
  28. // Overrides  
  29.     // ClassWizard generated virtual function overrides  
  30.     //{{AFX_VIRTUAL(CWinSunApp)  
  31.     public:  
  32.     virtual BOOL InitInstance();  
  33.     virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);  
  34.     //}}AFX_VIRTUAL  
  35.   
  36. // Implementation  
  37.   
  38.     //{{AFX_MSG(CWinSunApp)  
  39.         // NOTE - the ClassWizard will add and remove member functions here.  
  40.         //    DO NOT EDIT what you see in these blocks of generated code !  
  41.     //}}AFX_MSG  
  42.     DECLARE_MESSAGE_MAP()  
  43. };  
  44.   
  45.   
  46. /////////////////////////////////////////////////////////////////////////////  
  47.   
  48. //{{AFX_INSERT_LOCATION}}  
  49. // Microsoft Visual C++ will insert additional declarations immediately before the previous line.  
  50.   
  51. #endif // !defined(AFX_WINSUN_H__025D80ED_531B_42C3_8C9F_1EB3093C7BC9__INCLUDED_)  

WinSunApp.cpp

[cpp] view plaincopy
  1. // WinSun.cpp : Defines the class behaviors for the application.  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "WinSun.h"  
  6. #include "WinSunDlg.h"  
  7.   
  8. #ifdef _DEBUG  
  9. #define new DEBUG_NEW  
  10. #undef THIS_FILE  
  11. static char THIS_FILE[] = __FILE__;  
  12. #endif  
  13.   
  14. /////////////////////////////////////////////////////////////////////////////  
  15. // CWinSunApp  
  16.   
  17. BEGIN_MESSAGE_MAP(CWinSunApp, CWinApp)  
  18.     //{{AFX_MSG_MAP(CWinSunApp)  
  19.         // NOTE - the ClassWizard will add and remove mapping macros here.  
  20.         //    DO NOT EDIT what you see in these blocks of generated code!  
  21.     //}}AFX_MSG  
  22.     ON_COMMAND(ID_HELP, CWinApp::OnHelp)  
  23. END_MESSAGE_MAP()  
  24.   
  25. /////////////////////////////////////////////////////////////////////////////  
  26. // CWinSunApp construction  
  27.   
  28.   
  29. CWinSunApp::CWinSunApp()  
  30. {  
  31.     // TODO: add construction code here,  
  32.     // Place all significant initialization in InitInstance  
  33. }  
  34.   
  35. /////////////////////////////////////////////////////////////////////////////  
  36. // The one and only CWinSunApp object  
  37.   
  38. CWinSunApp theApp;  
  39.   
  40. /////////////////////////////////////////////////////////////////////////////  
  41. // CWinSunApp initialization  
  42.   
  43. BOOL CWinSunApp::InitInstance()  
  44. {  
  45.     AfxEnableControlContainer();  
  46.   
  47.     // Standard initialization  
  48.     // If you are not using these features and wish to reduce the size  
  49.     //  of your final executable, you should remove from the following  
  50.     //  the specific initialization routines you do not need.  
  51.   
  52. #ifdef _AFXDLL  
  53.     Enable3dControls();         // Call this when using MFC in a shared DLL  
  54. #else  
  55.     Enable3dControlsStatic();   // Call this when linking to MFC statically  
  56. #endif  
  57.   
  58.     CWinSunDlg dlg;  
  59.     m_pMainWnd = &dlg;  
  60.     int nResponse = dlg.DoModal();  
  61.     if (nResponse == IDOK)  
  62.     {  
  63.         // TODO: Place code here to handle when the dialog is     
  64.         //  dismissed with OK  
  65.     }  
  66.     else if (nResponse == IDCANCEL)  
  67.     {  
  68.         // TODO: Place code here to handle when the dialog is  
  69.         //  dismissed with Cancel  
  70.     }  
  71.   
  72.     // Since the dialog has been closed, return FALSE so that we exit the  
  73.     //  application, rather than start the application's message pump.  
  74.   
  75.     //将CWinSunApp类的成员变量设置为NULL  
  76.     m_hwndDlg =NULL;  
  77.   
  78.     return FALSE;  
  79. }  
  80.   
  81. //覆盖基类的虚函数,接管消息  
  82. BOOL CWinSunApp::ProcessMessageFilter(int code, LPMSG lpMsg)   
  83. {  
  84.     // TODO: Add your specialized code here and/or call the base class  
  85.       
  86.     if(m_hwndDlg!=NULL)  
  87.     {  
  88.         if(lpMsg->message==WM_KEYDOWN)  
  89.             AfxMessageBox("捕获WM_KEYDOWN成功!");  
  90.     }  
  91.       
  92.     return CWinApp::ProcessMessageFilter(code, lpMsg);  
  93. }  

WinSunDlg.h

[cpp] view plaincopy
  1. // WinSunDlg.h : header file  
  2. //  
  3.   
  4. #if !defined(AFX_WINSUNDLG_H__9DC85391_A9DD_4A1E_8380_6A32A3CF15EF__INCLUDED_)  
  5. #define AFX_WINSUNDLG_H__9DC85391_A9DD_4A1E_8380_6A32A3CF15EF__INCLUDED_  
  6.   
  7. #if _MSC_VER > 1000  
  8. #pragma once  
  9. #endif // _MSC_VER > 1000  
  10.   
  11. /////////////////////////////////////////////////////////////////////////////  
  12. // CWinSunDlg dialog  
  13.   
  14. class CWinSunDlg : public CDialog  
  15. {  
  16. // Construction  
  17. public:  
  18.     CWinSunDlg(CWnd* pParent = NULL);   // standard constructor  
  19.   
  20. // Dialog Data  
  21.     //{{AFX_DATA(CWinSunDlg)  
  22.     enum { IDD = IDD_WINSUN_DIALOG };  
  23.         // NOTE: the ClassWizard will add data members here  
  24.     //}}AFX_DATA  
  25.   
  26.     // ClassWizard generated virtual function overrides  
  27.     //{{AFX_VIRTUAL(CWinSunDlg)  
  28.     protected:  
  29.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support  
  30.     //}}AFX_VIRTUAL  
  31.   
  32. // Implementation  
  33. protected:  
  34.     HICON m_hIcon;  
  35.   
  36.     // Generated message map functions  
  37.     //{{AFX_MSG(CWinSunDlg)  
  38.     virtual BOOL OnInitDialog();  
  39.     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);  
  40.     afx_msg void OnPaint();  
  41.     afx_msg HCURSOR OnQueryDragIcon();  
  42.     afx_msg void OnDestroy();  
  43.     //}}AFX_MSG  
  44.     DECLARE_MESSAGE_MAP()  
  45. };  
  46.   
  47. //{{AFX_INSERT_LOCATION}}  
  48. // Microsoft Visual C++ will insert additional declarations immediately before the previous line.  
  49.   
  50. #endif // !defined(AFX_WINSUNDLG_H__9DC85391_A9DD_4A1E_8380_6A32A3CF15EF__INCLUDED_)  

WinSunDlg.cpp

[cpp] view plaincopy
  1. // WinSunDlg.cpp : implementation file  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "WinSun.h"  
  6. #include "WinSunDlg.h"  
  7.   
  8. #ifdef _DEBUG  
  9. #define new DEBUG_NEW  
  10. #undef THIS_FILE  
  11. static char THIS_FILE[] = __FILE__;  
  12. #endif  
  13.   
  14. /////////////////////////////////////////////////////////////////////////////  
  15. // CAboutDlg dialog used for App About  
  16.   
  17. class CAboutDlg : public CDialog  
  18. {  
  19. public:  
  20.     CAboutDlg();  
  21.   
  22. // Dialog Data  
  23.     //{{AFX_DATA(CAboutDlg)  
  24.     enum { IDD = IDD_ABOUTBOX };  
  25.     //}}AFX_DATA  
  26.   
  27.     // ClassWizard generated virtual function overrides  
  28.     //{{AFX_VIRTUAL(CAboutDlg)  
  29.     protected:  
  30.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support  
  31.     //}}AFX_VIRTUAL  
  32.   
  33. // Implementation  
  34. protected:  
  35.     //{{AFX_MSG(CAboutDlg)  
  36.     //}}AFX_MSG  
  37.     DECLARE_MESSAGE_MAP()  
  38. };  
  39.   
  40. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)  
  41. {  
  42.     //{{AFX_DATA_INIT(CAboutDlg)  
  43.     //}}AFX_DATA_INIT  
  44. }  
  45.   
  46. void CAboutDlg::DoDataExchange(CDataExchange* pDX)  
  47. {  
  48.     CDialog::DoDataExchange(pDX);  
  49.     //{{AFX_DATA_MAP(CAboutDlg)  
  50.     //}}AFX_DATA_MAP  
  51. }  
  52.   
  53. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)  
  54.     //{{AFX_MSG_MAP(CAboutDlg)  
  55.         // No message handlers  
  56.     //}}AFX_MSG_MAP  
  57. END_MESSAGE_MAP()  
  58.   
  59. /////////////////////////////////////////////////////////////////////////////  
  60. // CWinSunDlg dialog  
  61.   
  62. CWinSunDlg::CWinSunDlg(CWnd* pParent /*=NULL*/)  
  63.     : CDialog(CWinSunDlg::IDD, pParent)  
  64. {  
  65.     //{{AFX_DATA_INIT(CWinSunDlg)  
  66.         // NOTE: the ClassWizard will add member initialization here  
  67.     //}}AFX_DATA_INIT  
  68.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32  
  69.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);  
  70. }  
  71.   
  72. void CWinSunDlg::DoDataExchange(CDataExchange* pDX)  
  73. {  
  74.     CDialog::DoDataExchange(pDX);  
  75.     //{{AFX_DATA_MAP(CWinSunDlg)  
  76.         // NOTE: the ClassWizard will add DDX and DDV calls here  
  77.     //}}AFX_DATA_MAP  
  78. }  
  79.   
  80. BEGIN_MESSAGE_MAP(CWinSunDlg, CDialog)  
  81.     //{{AFX_MSG_MAP(CWinSunDlg)  
  82.     ON_WM_SYSCOMMAND()  
  83.     ON_WM_PAINT()  
  84.     ON_WM_QUERYDRAGICON()  
  85.     ON_WM_DESTROY()  
  86.     //}}AFX_MSG_MAP  
  87. END_MESSAGE_MAP()  
  88.   
  89. /////////////////////////////////////////////////////////////////////////////  
  90. // CWinSunDlg message handlers  
  91.   
  92. BOOL CWinSunDlg::OnInitDialog()  
  93. {  
  94.     CDialog::OnInitDialog();  
  95.   
  96.     // Add "About..." menu item to system menu.  
  97.   
  98.     // IDM_ABOUTBOX must be in the system command range.  
  99.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);  
  100.     ASSERT(IDM_ABOUTBOX < 0xF000);  
  101.   
  102.     CMenu* pSysMenu = GetSystemMenu(FALSE);  
  103.     if (pSysMenu != NULL)  
  104.     {  
  105.         CString strAboutMenu;  
  106.         strAboutMenu.LoadString(IDS_ABOUTBOX);  
  107.         if (!strAboutMenu.IsEmpty())  
  108.         {  
  109.             pSysMenu->AppendMenu(MF_SEPARATOR);  
  110.             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);  
  111.         }  
  112.     }  
  113.   
  114.     // Set the icon for this dialog.  The framework does this automatically  
  115.     //  when the application's main window is not a dialog  
  116.     SetIcon(m_hIcon, TRUE);         // Set big icon  
  117.     SetIcon(m_hIcon, FALSE);        // Set small icon  
  118.       
  119.     // TODO: Add extra initialization here  
  120.   
  121.     //将对话框的句柄传递到CWinSunApp类中  
  122.     ((CWinSunApp*)AfxGetApp())->m_hwndDlg =this->m_hWnd;  
  123.       
  124.     return TRUE;  // return TRUE  unless you set the focus to a control  
  125. }  
  126.   
  127. void CWinSunDlg::OnSysCommand(UINT nID, LPARAM lParam)  
  128. {  
  129.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)  
  130.     {  
  131.         CAboutDlg dlgAbout;  
  132.         dlgAbout.DoModal();  
  133.     }  
  134.     else  
  135.     {  
  136.         CDialog::OnSysCommand(nID, lParam);  
  137.     }  
  138. }  
  139.   
  140. // If you add a minimize button to your dialog, you will need the code below  
  141. //  to draw the icon.  For MFC applications using the document/view model,  
  142. //  this is automatically done for you by the framework.  
  143.   
  144. void CWinSunDlg::OnPaint()   
  145. {  
  146.     if (IsIconic())  
  147.     {  
  148.         CPaintDC dc(this); // device context for painting  
  149.   
  150.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);  
  151.   
  152.         // Center icon in client rectangle  
  153.         int cxIcon = GetSystemMetrics(SM_CXICON);  
  154.         int cyIcon = GetSystemMetrics(SM_CYICON);  
  155.         CRect rect;  
  156.         GetClientRect(&rect);  
  157.         int x = (rect.Width() - cxIcon + 1) / 2;  
  158.         int y = (rect.Height() - cyIcon + 1) / 2;  
  159.   
  160.         // Draw the icon  
  161.         dc.DrawIcon(x, y, m_hIcon);  
  162.     }  
  163.     else  
  164.     {  
  165.         CDialog::OnPaint();  
  166.     }  
  167. }  
  168.   
  169. // The system calls this to obtain the cursor to display while the user drags  
  170. //  the minimized window.  
  171. HCURSOR CWinSunDlg::OnQueryDragIcon()  
  172. {  
  173.     return (HCURSOR) m_hIcon;  
  174. }  
  175.   
  176. void CWinSunDlg::OnDestroy()   
  177. {  
  178.     CDialog::OnDestroy();  
  179.       
  180.     // TODO: Add your message handler code here  
  181.       //对话框窗口销毁后,将CWinSumApp类中的变量m_hwndDlg置为NULL  
  182.         ((CWinSunApp*)AfxGetApp())->m_hwndDlg =NULL;  
  183. }  

//---

//---


//---编译运行,试着按下键盘任意一个键:

//---

0 0
原创粉丝点击