私はこれに苦労しており、正しい手順としてこれを推奨するいくつかのstackoverflowの投稿を見てきました:
クリックスルーで常に最前面に表示される透明なウィンドウ レイヤー
私のコードでは、この手法をほぼ正確に踏襲しています。それでも、私のコードは機能せず、その理由が少しわかりません。間違った手順を使用していないかどうか疑問に思っていますか? 明確にするために、私が望む効果は、ユーザーがフォームをクリックして、その下にある何かにアクセスすることです。たとえば、ビジュアルスタジオの上で実行しています。アプリをクリックしようとすると、代わりに Visual Studio をクリックします。
アップデート:
コードを呼び出すと、次の 2 つのいずれかが発生します (setwindowlong メソッドを呼び出す場所によって異なります)。
- ウィンドウが描画されない
- ウィンドウは描画されますが、クリック可能です
オプション 1 は、initializecomponent の直後にコードを実行すると発生します オプション 2 は、initializecomponent の前にコードを実行すると発生します
何よりも先にフォームを描画する完全なコードは次のとおりです。
[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
public frmPhoneQueueViewer()
{
InitializeComponent();
// Set the form click-through
int initialStyle = GetWindowLong(this.Handle, -20);
SetWindowLong(this.Handle, -20, initialStyle | 0x80000 | 0x20);
//Get height of taskbar to exclude it, then bind to lower right of screen
int nTaskBarHeight = Screen.PrimaryScreen.Bounds.Bottom -Screen.PrimaryScreen.WorkingArea.Bottom;
Rectangle workingArea = Screen.GetWorkingArea(this);
this.Location = new Point(Screen.PrimaryScreen.Bounds.Right - this.Size.Width, workingArea.Bottom - Size.Height + nTaskBarHeight);
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
this.ControlBox = false;
this.Text = string.Empty;
this.ShowInTaskbar = false;
PopulatePhoneQueueData();
}