2009-10-06 2 views
9

以前の回答をありがとうございました。マウス座標の大きな赤い十字を示す基本的なツールを完成させてくれました。赤い十字は透明な背景の透明な背景を持つ画像です。問題は、フォームの上端と中央が実際にマウスxyに配置されているため、クリックスルーできないことです。どのように十字をカーソル上に表示させるが、「クリック可能」にするために、これを使用可能にする方法はありますか?一番上のフォームで「スルー」をクリックすると可能ですか?

答えて

8

あなたはWS_EX_TRANSPARENTウィンドウのスタイルを設定するためにSetWindowLongを使用することができます。

レイヤードウィンドウがWS_EX_TRANSPARENT拡張ウィンドウスタイルを持っている場合は、レイヤードウィンドウの形状は無視され、マウスイベントが渡されますレイヤードウィンドウの下にある他のウィンドウ。

CodeProjectには、テクニックの詳細が記載されています。this VB.NETにはありますが、C#に変換するのは簡単です。

public enum GWL 
{ 
    ExStyle = -20 
} 

public enum WS_EX 
{ 
    Transparent = 0x20, 
    Layered = 0x80000 
} 

public enum LWA 
{ 
    ColorKey = 0x1, 
    Alpha = 0x2 
} 

[DllImport("user32.dll", EntryPoint = "GetWindowLong")] 
public static extern int GetWindowLong(IntPtr hWnd, GWL nIndex); 

[DllImport("user32.dll", EntryPoint = "SetWindowLong")] 
public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, int dwNewLong); 

[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")] 
public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, LWA dwFlags); 

protected override void OnShown(EventArgs e) 
{ 
    base.OnShown(e); 
    int wl = GetWindowLong(this.Handle, GWL.ExStyle); 
    wl = wl | 0x80000 | 0x20; 
    SetWindowLong(this.Handle, GWL.ExStyle, wl); 
    SetLayeredWindowAttributes(this.Handle, 0, 128, LWA.Alpha); 
} 

をそれはまた、他のどこかからコピーされました:

私は過去に次のコードを使用しています。ここでの重要な行は、OnShownメソッドにあります。私はライン

wl = wl | 0x80000 | 0x20; 

がWS_EX_LAYEREDとWS_EX_TRANSPARENT拡張スタイルを設定し、少し不可解であることを認めざるを得ないけれども。

あなたはおそらくもまた、透明性のキー(上記のバージョンと黒ではない)としてTransparencyKeyを使用して、より詳細/コメントバージョンを、提供するために

wl = wl | WS_EX.Layered | WS_EX.Transparent; 
+0

もう少し詳細を教えてください。私はこの低レベルのAPIで経験していない、ありがとう! – Petr

+0

ありがとう、これは本当に素晴らしい場所、そのような迅速な答えです。 – Petr

+0

SetLayeredWindowAttributesを使用すると、以前にVS Designerで設定された透明度が失われ、フォームが半透明になりました。 しかし、この行を無効にすることは "クリック可能"なエフェクトには影響しません。 – Petr

0

ようにそれを設定することができ、かつ、必要に応じて1は、_alpha設定するかもしれません。

 /// <summary> 
     /// 0: the window is completely transparent ... 255: the window is opaque 
     /// </summary> 
     private byte _alpha; 

     private enum GetWindowLong 
     { 
      /// <summary> 
      /// Sets a new extended window style. 
      /// </summary> 
      GWL_EXSTYLE = -20 
     } 

     private enum ExtendedWindowStyles 
     { 
      /// <summary> 
      /// Transparent window. 
      /// </summary> 
      WS_EX_TRANSPARENT = 0x20, 
      /// <summary> 
      /// Layered window. http://msdn.microsoft.com/en-us/library/windows/desktop/ms632599%28v=vs.85%29.aspx#layered 
      /// </summary> 
      WS_EX_LAYERED = 0x80000 
     } 

     private enum LayeredWindowAttributes 
     { 
      /// <summary> 
      /// Use bAlpha to determine the opacity of the layered window. 
      /// </summary> 
      LWA_COLORKEY = 0x1, 
      /// <summary> 
      /// Use crKey as the transparency color. 
      /// </summary> 
      LWA_ALPHA = 0x2 
     } 

     [DllImport("user32.dll", EntryPoint = "GetWindowLong")] 
     private static extern int User32_GetWindowLong(IntPtr hWnd, GetWindowLong nIndex); 

     [DllImport("user32.dll", EntryPoint = "SetWindowLong")] 
     private static extern int User32_SetWindowLong(IntPtr hWnd, GetWindowLong nIndex, int dwNewLong); 

     [DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")] 
     private static extern bool User32_SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte bAlpha, LayeredWindowAttributes dwFlags); 

     protected override void OnShown(EventArgs e) 
     { 
      base.OnShown(e); 
      //Click through 
      int wl = User32_GetWindowLong(this.Handle, GetWindowLong.GWL_EXSTYLE); 
      User32_SetWindowLong(this.Handle, GetWindowLong.GWL_EXSTYLE, wl | (int)ExtendedWindowStyles.WS_EX_LAYERED | (int)ExtendedWindowStyles.WS_EX_TRANSPARENT); 
      //Change alpha 
      User32_SetLayeredWindowAttributes(this.Handle, (TransparencyKey.B << 16) + (TransparencyKey.G << 8) + TransparencyKey.R, _alpha, LayeredWindowAttributes.LWA_COLORKEY | LayeredWindowAttributes.LWA_ALPHA); 
     } 
関連する問題