ユーザーの画面にポップアップするフォームがありますTopMost=true
が、フォーカスが奪われます。最初に表示されたときにフォーカスを盗まないようにするにはどうすればよいですか?
7 に答える
これが私のために働いたものです。TopMost を提供しますが、フォーカスを盗むことはありません。
protected override bool ShowWithoutActivation
{
get { return true; }
}
private const int WS_EX_TOPMOST = 0x00000008;
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= WS_EX_TOPMOST;
return createParams;
}
}
Visual Studio デザイナなどで TopMost の設定を省略することを忘れないでください。
これは、ここから盗用された、エラー、借用されたものです ([回避策] をクリックしてください):
このコードをフォームに貼り付けます。
protected override bool ShowWithoutActivation
{
get { return true; }
}
次のように実行できます。
private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern bool SetWindowPos(
int hWnd, // Window handle
int hWndInsertAfter, // Placement-order handle
int X, // Horizontal position
int Y, // Vertical position
int cx, // Width
int cy, // Height
uint uFlags); // Window positioning flags
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);
public static void ShowInactiveTopmost(System.Windows.Forms.Form frm)
{
try
{
ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
frm.Left, frm.Top, frm.Width, frm.Height,
SWP_NOACTIVATE);
}
catch (System.Exception ex)
{
// error handling
}
}
form1のタイマーを使用して以下のコードをテストし、form1を所有者としてform2をインスタンス化して表示しました。
次に、form2のShownイベントで、現在アクティブなフォームである所有者にフォーカスを設定します。
form1にテキストボックスがあり、このプロセス中にフォーカスを失うことなく、テキストボックスに継続的に書き込むことができました。
form1の私のタイマーコード:
private void timer1_Tick(object sender, EventArgs e)
{
Form2 popup = new Form2();
popup.TopMost = true;
popup.Show(this);
timer1.Enabled = false;
}
form2のShowedイベントの私のコード:
private void Form2_Shown(object sender, EventArgs e)
{
this.Owner.Focus();
}
これを行うか、TopMostをfalseに設定して、HansPassantが述べたようにShowWithoutActivationのオーバーライドを使用できます。
編集:(または、これを書いているときに見逃したハンス・パッサントの追加コメントに見られるように、p / invokeを使用してください)
私は同じ問題に遭遇しました。私はC#ではなくC++を使用しています。とにかくこれが役立つと思います:
windows.h の使用:
BOOL WINAPI SetWindowPos(
__in HWND hWnd,
__in_opt HWND hWndInsertAfter,
__in int X,
__in int Y,
__in int cx,
__in int cy,
__in UINT uFlags
);
フラグ SWP_NOACTIVATE を uFlags 引数に渡すとうまくいきました。
イベントで書く代わりに.setfocus()
; フォームのイベントに_activated
書き込みます。.shown