1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      如何在對話框程序中讓對話框捕獲WM_KEYDOWN消息

      更新時間: 2007-05-16 13:33:54來源: 粵嵌教育瀏覽量:827


        在對話框程序中,我們經(jīng)常是利用對話框上的子控件進行命令響應(yīng)來處理一些事件。如果我們想要讓對話框(子控件的父窗口)類來響應(yīng)我們的按鍵消息,我們可以通過ClassWizard對WM_KEYDOWN消息進行響應(yīng),當程序運行后,我們按下鍵盤上的按鍵,但對話框不會有任何的反應(yīng)。這是因為在對話框程序中,某些特定的消息,例如按鍵消息,它們被Windows內(nèi)部的對話框過程處理了(即在基類中完成了處理,有興趣的讀者可以查看MFC的源代碼),或者被發(fā)送給子控件進行處理,所以我們在對話框類中就捕獲不到按鍵的消息了。

        既然我們知道了這個處理的過程,我們就可以找到底層處理按鍵消息的函數(shù),然后在子類中重載它,就可以在對話框程序中處理按鍵消息了。在MFC中,是利用BOOL ProcessMessageFilter(int code, LPMSG lpMsg)這個虛函數(shù)來過濾或響應(yīng)菜單和對話框的特定Windows消息。下面我們通過程序給大家演示基于對話框的應(yīng)用程序?qū)M_KEYDOWN消息的捕獲。

        步:新建一個工程,選擇MFC AppWizard (exe),工程名為WinSun,點擊ok,進入下一步,選擇Dialog based,點擊Finish。
        第二步:在CWinSunApp類上點擊右鍵,選擇Add Member Varialbe,增加一個類型為HWND,變量名m_hwndDlg的public的變量。代碼如下:

      WinSun.h

      class CWinSunApp : public CWinApp

      {

      public:

      HWND m_hwndDlg;

      CWinSunApp();



      // Overrides

      // ClassWizard generated virtual function overrides

      //{{AFX_VIRTUAL(CWinSunApp)

      public:

      virtual BOOL InitInstance();

      //}}AFX_VIRTUAL



      // Implementation



      //{{AFX_MSG(CWinSunApp)

      // NOTE - the ClassWizard will add and remove member functions here.

      // DO NOT EDIT what you see in these blocks of generated code !

      //}}AFX_MSG

      DECLARE_MESSAGE_MAP()

      };



        第三步:在WinSun.cpp(CWinSunApp類)文件中的InitInstance()函數(shù)中添加如下代碼:

      WinSun.cpp

      BOOL CWinSunApp::InitInstance()

      {

      AfxEnableControlContainer();



      // Standard initialization

      // If you are not using these features and wish to reduce the size

      // of your final executable, you should remove from the following

      // the specific initialization routines you do not need.



      #ifdef _AFXDLL

      Enable3dControls(); // Call this when using MFC in a shared DLL

      #else

      Enable3dControlsStatic(); // Call this when linking to MFC statically

      #endif



      CWinSunDlg dlg;

      m_pMainWnd = &dlg;

      int nResponse = dlg.DoModal();

      if (nResponse == IDOK)

      {

      // TODO: Place code here to handle when the dialog is

      // dismissed with OK

      }

      else if (nResponse == IDCANCEL)

      {

      // TODO: Place code here to handle when the dialog is

      // dismissed with Cancel

      }



      // Since the dialog has been closed, return FALSE so that we exit the

      // application, rather than start the application's message pump.

      m_hwndDlg=NULL;

      return FALSE;

      }



        第四步:在CWinSunApp類上點擊右鍵,選擇Add Virtual Function,在左邊一欄里,選擇ProcessMessageFilter,在右邊按鈕上選擇Add and Edit,然后加入以下代碼:

      WinSun.cpp

      BOOL CWinSunApp::ProcessMessageFilter(int code, LPMSG lpMsg)

      {

      // TODO: Add your specialized code here and/or call the base class

      if(m_hwndDlg!=NULL)

      {

      //判斷消息,如果消息是從對話框發(fā)出的或者其子控件發(fā)出的,我們就進行處理。sunxin

      if((lpMsg->hwnd==m_hwndDlg) || ::IsChild(m_hwndDlg,lpMsg->hwnd))

      {

      //如果消息是WM_KEYDOWN,我們就彈出一個消息框。sunxin

      if(lpMsg->message==WM_KEYDOWN)

      {

      AfxMessageBox("捕獲WM_KEYDOWN消息成功!");

      }

      }

      }

      return CWinApp::ProcessMessageFilter(code, lpMsg);

      }



        第五步:在WinSunDlg.cpp(CWinSunDlg類)中的OnInitialDialog()函數(shù)中加入以下代碼:

      WinSunDlg.cpp

      BOOL CWinSunDlg::OnInitDialog()

      {

      CDialog::OnInitDialog();



      // Add "About..." menu item to system menu.



      // IDM_ABOUTBOX must be in the system command range.

      ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

      ASSERT(IDM_ABOUTBOX < 0xF000);



      CMenu* pSysMenu = GetSystemMenu(FALSE);

      if (pSysMenu != NULL)

      {

      CString strAboutMenu;

      strAboutMenu.LoadString(IDS_ABOUTBOX);

      if (!strAboutMenu.IsEmpty())

      {

      pSysMenu->AppendMenu(MF_SEPARATOR);

      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

      }

      }



      // Set the icon for this dialog. The framework does this automatically

      // when the application's main window is not a dialog

      SetIcon(m_hIcon, TRUE); // Set big icon

      SetIcon(m_hIcon, FALSE); // Set small icon



      // TODO: Add extra initialization here

      //將對話框的句柄傳遞到CWinSunApp類中。sunxin

      ((CWinSunApp*)AfxGetApp())->m_hwndDlg=m_hWnd;

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

      }



        第六步:在對話框窗口銷毀后,將CWinSunApp類中的變量m_hwndDlg置為NULL,為此我們在CWinSunDlg類上點擊右鍵,選擇Add Windows Message Handler,在左邊一欄中選擇WM_DESTROY,在右邊按鈕上選擇Add and Edit,然后加入以下代碼:

      WinSunDlg.cpp

      void CWinSunDlg::OnDestroy()

      {

      CDialog::OnDestroy();



      // TODO: Add your message handler code here

      ((CWinSunApp*)AfxGetApp())->m_hwndDlg=NULL;

      }

        至此,我們的工作就做完了,現(xiàn)在我們可以按Ctrl+F5運行程序,看到我們想要的結(jié)果。當然,如果我們想捕獲WM_KEYUP或WM_CHAR消息,也是類似,這就交給讀者下來自行完成了。

      免費預(yù)約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 亚洲一区二区三区乱码AⅤ 在线播放国产日韩 | 亚洲国产理论片在线观看 | 精品97免费公开视频 | 日本新一二三区不卡在线观看 | 亚洲欧美日韩国产精品蜜月a | 亚洲成AV人片在线视 |