2010-07-30 64 views
0

主窗體打開一個子窗體,其上有少量按鈕CONTROL。我需要捕捉鍵盤事件,所以我將其中一個控件分類。一切都很好,直到控制失敗爲止。C++子類化表單以捕獲F1 - F12鍵

理想情況下,只要此子窗體打開,我想將焦點分配給此控件,從而捕獲所有擊鍵,無論用戶點擊的位置如何。

我懷疑超類可能是更好的方法,但我不太熟悉它。

也許我應該做的是在主窗體上使用加速器?

新增: 我要指出的主要形式有其子類恢復向上/向下箭頭和鼠標滾輪等

+3

您應該添加一個標籤,指定您正在使用哪種GUI框架,因爲這不是C++標準的一部分。如果他們必須猜測這些,人們將無法幫助你。 – sellibitze 2010-07-30 09:12:07

回答

0

假設這是在Windows和Win32 API中,一個選項是在主GetMessageTranslateMessage,DispatchMessage循環中查找消息。你可以在這個循環中對任何消息進行特殊處理,而不管它針對哪個窗口。

您應該使用IsChild來檢查消息是否適用於主窗口上的控件(而不是可能單獨顯示的某個對話框或消息框)。正確理解邏輯也很麻煩。只有在只有攔截消息,當你知道你的控制已經失去焦點,並只有截取你需要的確切消息。

幾年前,我寫了一個庫消息循環,內置了很多這樣的函數。我有一個簡單的管理類,它指向我自己的小窗口類的實例。循環知道對話框和普通窗口之間的區別,給每個窗口類有機會窺探它的孩子的消息,等等。你將不能夠直接運行這個和慣例有一些奇怪,但你可能會發現這很有用...

int c_Window_List::Message_Loop (void) 
{ 
    MSG msg; 
    bool l_Handled; 

    while (GetMessage (&msg, NULL, 0, 0)) 
    { 
    l_Handled = false; 

    c_Windows::c_Cursor l_Cursor; 
    bool    ok; 

    for (ok = l_Cursor.Find_First (g_Windows); ok; ok = l_Cursor.Step_Next()) 
    { 
     if (IsChild (l_Cursor.Key(), msg.hwnd)) 
     { 
     if (l_Cursor.Data().f_Accelerators != NULL) 
     { 
      l_Handled = TranslateAccelerator (l_Cursor.Key(), l_Cursor.Data().f_Accelerators, &msg); 

      if (l_Handled) break; 
     } 

     if (l_Cursor.Data().f_Manager != 0) 
     { 
      l_Handled = l_Cursor.Data().f_Manager->Spy_Msg (l_Cursor.Key(), msg); 
     } 

     if (l_Handled) break; 

     if (l_Cursor.Data().f_Is_Dialog) 
     { 
      l_Handled = IsDialogMessage (l_Cursor.Key(), &msg); 
      if (l_Handled) break; 
     } 
     } 
    } 

    if (!l_Handled) 
    { 
     TranslateMessage (&msg); 
     DispatchMessage (&msg); 
    } 

    if (g_Windows.Size() == 0) 
    { 
     // When all windows have closed, exit 
     PostQuitMessage (0); 
    } 
    } 

    return msg.wParam; 
} 

f_前綴平均場 - 我拿起m_會議之後,但是這代碼在很長一段時間內還沒有被重新審視過。 f_Manager特別指向我的c_Window_Base類的實例。 c_Cursor類是一種迭代器,用於遍歷存儲在g_Windows變量(實際上是靜態類成員而不是全局變量)中的所有窗口。

+0

由於父對象和子對話都是無模式的,我選擇從msg中捕獲所有關鍵筆劃,在msg中查找WM_KEYDOWN。消息然後VK_F1 - VK_F12在msg.wParam的消息泵。 – 2010-08-03 07:46:49

1

傳統的方法是安裝一個鍵盤鉤子(SetWindowsHookEx)大ListView控件,但你需要將它注入到每個應用程序中,並且它不能在32/64位邊界上工作。

然而,你可以做什麼,而且很容易就是在計時器上用GetKeyboardState輪詢鍵盤,並檢查你的f1-f12鍵是否被激活。定時器可以像100ms一樣慢,它幾乎可以捕捉幾乎所有的東西,而幾乎不使用任何資源。

+0

作爲它爲Windows完成的方式+1,但正如sellibitze所說... – Steve314 2010-07-30 09:22:17

+0

heh甚至不認爲它可能不適用於windows,也習慣於僅爲它編程。 – Blindy 2010-07-30 09:24:58

+0

完成。 Windows 32bit – 2010-07-30 09:27:36