2010-09-30 103 views
2

我想在沒有表單的地方檢索Ctrl鍵的狀態。WinForms檢索沒有窗體/用戶控件的鍵盤狀態

通常要得到一個關鍵的狀態,我會使用Control_KeyDown/KeyUp事件。但是,需要知道Ctrl是否被按下的代碼不在任何形式之中。有一個窗體顯示,但代碼而不是依賴於該窗體,但它自己找到關鍵狀態。

當然有辦法做到這一點,只有我沒有成功地在谷歌上找到它。

請注意,儘管代碼沒有「有」表單可用,但它仍然是一個WinForms應用程序,因此框架可能爲我提供了一些類/對象來實現該目標。

背景:

在應用程序啓動階段,我想,如果Ctrl鍵的那一刻被按下的一個步驟differntly行爲。啓動階段顯示啓動畫面,但啓動的代碼不知道這一點。相反,它會向回調報告進度,並且回調會更新啓動屏幕。

如果我使用啓動畫面來獲取KeyDown事件,我使啓動代碼依賴於該啓動畫面,該啓動畫面引入了循環依賴。我想保留刪除閃屏的自由,並用不同的東西替換。

+0

這是否意味着你的應用程序需要知道,如果Ctrl鍵點擊,無論哪個應用是活動一?所以如果你在任何程序中工作並點擊Ctrl,你想讓你的程序抓住它?在這種情況下,它是一個鍵盤鉤子你以後。如果你確認這一點,我可以給你幾個指示。 – 2010-09-30 10:33:23

+0

@Øyvind:如果另一個應用程序在前面,則不需要注意Ctrl。事實上,如果在這種情況下Ctrl *未註冊,它甚至會更好(請參閱關於我的問題背景的更新)。 – chiccodoro 2010-09-30 11:54:35

回答

10

你可以使用上Control靜態方法稱爲ModifierKeys

Control.ModifierKeys on MSDN

如:

if (Control.ModifierKeys == Keys.Control) 
{ 
    //... 
} 
+0

我幾天前試過這個,但它沒有工作,因爲在這個階段(使用初始屏幕初始化)事件循環還沒有運行。 (另見對testalino的評論)。現在,啓動畫面在消息循環中運行,並且解決方案正常工作。 – chiccodoro 2010-10-06 14:10:01

3

我究竟做了,最近剛:

static class NativeMethods 
    { 
     public static bool IsControlKeyDown() 
     { 
      return (GetKeyState(VK_CONTROL) & KEY_PRESSED) != 0; 
     } 
     private const int KEY_PRESSED = 0x8000; 
     private const int VK_CONTROL = 0x11; 
     [System.Runtime.InteropServices.DllImport("user32.dll")] 
     static extern short GetKeyState(int key); 
    } 

測試代碼,創建一個新的控制檯應用程序,並使用以下主要方法:

static void Main(string[] args) 
    { 
     for (int i = 0; i < 100; i++) 
     { 
      Console.WriteLine(NativeMethods.IsControlKeyDown()); 
      System.Threading.Thread.Sleep(100); 
     } 
    } 
+0

謝謝,看起來不錯。還有一種非本地方式嗎? – chiccodoro 2010-09-30 10:38:12

+0

幾天前我找不到任何非本機解決方案。 – testalino 2010-09-30 10:42:52

+0

@testalino:我已經複製並粘貼了你的代碼,並且添加了一個對IsControlKeyDown()的調用,但是即使我同時按下兩個Ctrl鍵,它也會返回false。 – chiccodoro 2010-09-30 12:33:31

0

你就不能抓Ctrl被按下,被顯示,因爲這種形式似乎也是應用程序的一部分,並使用表單可以調用的事件將點擊轉發到代碼的「無形」部分?

我可能會誤解你是什麼這裏經過,但看起來至少一個選項。

+0

是的,我也在考慮這種方法。但在我的情況下,它引入了我寧願防止的依賴項(請參閱我的問題的更新)。 – chiccodoro 2010-09-30 11:55:22