2009-03-24 1 views
2

この投稿への参照。RegisterHotKey APIコールを使用すると、なぜそれが修飾子として1,2,4、および8を受け入れるのですか?

http://www.pinvoke.net/default.aspx/user32/RegisterHotKey.html

#region fields 
    public static int MOD_ALT = 0x1; 
    public static int MOD_CONTROL = 0x2; 
    public static int MOD_SHIFT = 0x4; 
    public static int MOD_WIN = 0x8; 
    public static int WM_HOTKEY = 0x312; 
    #endregion 

    [DllImport("user32.dll")] 
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc); 

    [DllImport("user32.dll")] 
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id); 

    private static int keyId; 
    public static void RegisterHotKey(Form f, Keys key) 
    { 
     int modifiers = 0; 

     if ((key & Keys.Alt) == Keys.Alt) 
      modifiers = modifiers | WindowsShell.MOD_ALT; 

     if ((key & Keys.Control) == Keys.Control) 
      modifiers = modifiers | WindowsShell.MOD_CONTROL; 

     if ((key & Keys.Shift) == Keys.Shift) 
      modifiers = modifiers | WindowsShell.MOD_SHIFT; 

     Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt; 

     Func ff = delegate() 
      { 
       keyId = f.GetHashCode(); // this should be a key unique ID, modify this if you want more than one hotkey 
       RegisterHotKey((IntPtr)f.Handle, keyId, modifiers, (int)k); 
      }; 

     f.Invoke(ff); // this should be checked if we really need it (InvokeRequired), but it's faster this way 
    } 

私の質問は、どのようにRegisterHotKey APIは1248は、Windowsキーがあることを知っているんですか? ctrl、shift、およびmenu(alt)のキーコードはキーの値が全く異なるため、そして、まさにそれがためにチェックしていますRegisterHotKey機能で起こっている:

if ((key & Keys.Control) == Keys.Control) 
       modifiers = modifiers | WindowsShell.MOD_CONTROL; 

、それはここで何をしているのですか?など

Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt; 

答えて

5

MOD_ALTMOD_CONTROL、関連付けられたキーのキーコードに任意の関係を持っていません。

flagsを表すのにenumタイプが使用されています。これは、(同時に押された修飾キー、ファイルアクセス許可などの)物の組み合わせを表す状態を表現する特にコンパクトな方法です。

このようにenumを使用すると、列挙型の変数の各ビットは次のようになります。特定の「フラグ」が設定されていることを示すために使用することができます。

// Note that powers of 2 are used; each value has only a single bit set 
public static int MOD_ALT = 0x1;  // If bit 0 is set, Alt is pressed 
public static int MOD_CONTROL = 0x2; // If bit 1 is set, Ctrl is pressed 
public static int MOD_SHIFT = 0x4; // If bit 2 is set, Shift is pressed 
public static int MOD_WIN = 0x8;  // If bit 3 is set, Win is pressed 

// If we wanted to represent a combination of keys: 
int altAndControl = MOD_ALT | MOD_CONTROL; // == 3 
int controlAndShift = MOD_CONTROL | MOD_SHIFT; // == 6 

これには2つの利点があります。

  • APIは、キーのすべての修飾のために、個々のブール・パラメータを取る必要はありません
  • APIは変更せずに、追加の修飾キーを含むように拡張することができ
  • インタフェース

& sおよび| S値に設定されるフラグを決定するために用いることができるビット単位、および秒または値にフラグを設定解除する。

あなたがについて尋ねてきたコードは、まさにこのん:「キーはControlビットがセットされている場合はmodifiersに制御ビットを設定し、その後、」

if ((key & Keys.Control) == Keys.Control) 
    modifiers = modifiers | WindowsShell.MOD_CONTROL 

Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt; 

されると言っています「kControlShift、およびAltフラグがクリアされたkeyが割り当てられていると言う。

なぜ私がpinvokeへの貢献者が定数を使うのを選んだのか分かりません。あなたは同じように簡単に、適切な列挙型を使用することができます。

[Flags] 
public enum Modifiers 
{ 
    None = 0, 
    Alt = 1, 
    Control = 2, 
    // ... 
} 

My answer to a similar questionは、いくつかのフラグがどのように動作するかの詳細、およびより多くの例があります。

+0

を使用するのと同じやり方で、この作品? [フラグ()] パブリック列挙KeyModifiers最も私を混乱させる {なし= 0、 アルト= 1、 コントロール= 2、 シフト= 4、 のWindows = 8 } 部分が改質であります引数。 fsModifiersは0x2 == CTRLキーをどのように知っていますか?それは内部機能ですか? DLLのAPIから? –

+0

はい、APIの内部にあります。 –

+0

はい、それは同じように動作するはずです。 –

0

あなたはここを見て、RegisterHotKey APIの詳細をお知りになりたい場合は:MOD_ALT、MOD_CONTROLの定義値のためWINUSER.Hを見てプラットフォームSDKをダウンロードし、

API Help

をまた、

1

1、2、4、8は、単一ビットを表すために使用されます。 1が最下位ビットがオンになります。 2を加えると2番目の最下位ビットなどがオンになります。したがって、複数のフラグを互いに独立して設定することができます。あなたが真であると2と4で表される変数を設定したい場合は

1 = 0001 
2 = 0010 
4 = 0100 
8 = 1000 

したがって、あなたは、0110 = 6

関連する問題