关闭表单未在应用程序openforms中显示

时间:2015-01-27 15:40:14

标签: c# winforms winapi user32

我使用下面的代码在屏幕上弹出一个表单,但它并没有窃取焦点。

这很好用,但我现在需要关闭表单,表单本身不会显示在Application.OpenForms

我该怎么做?

设置并打开表单

frmClientCall frm = new frmClientCall {StartPosition = FormStartPosition.Manual, Text = "Phone Call"};
frm.Location = new System.Drawing.Point(
    Screen.PrimaryScreen.WorkingArea.Width - frm.Width,
    Screen.PrimaryScreen.WorkingArea.Height - frm.Height - 202
);
frm.lblClient.Text = URI;
frm.ShowInactiveTopmost();

防止关注表单的代码

private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
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

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

public void ShowInactiveTopmost()
{
    ShowWindow(Handle, SW_SHOWNOACTIVATE);
    SetWindowPos(Handle.ToInt32(), HWND_TOPMOST, Left, Top, Width, Height, SWP_NOACTIVATE);

}

1 个答案:

答案 0 :(得分:4)

是的,这不是唯一的不幸事故。例如,您还可以看到表单的Load事件永远不会触发。基本问题是你绕过了正常的逻辑,这在Winforms中是一个非常大的问题,因为它懒惰地创建了本机窗口。在您的情况下,当您使用Handle属性时会发生这种情况。我认为潜在的问题是Visible属性从未被设置为 true ,这是真正让球滚动的那个。

好吧,不要这样做,Winforms已经支持显示窗口而不激活它。将此代码粘贴到您想要显示的表单中而不激活:

    protected override bool ShowWithoutActivation {
        get { return true; }
    }

SetWindowPos()pinvoke使其最顶层也不是必需的,粘贴此代码:

    protected override CreateParams CreateParams {
        get {
            var cp = base.CreateParams;
            cp.ExStyle |= 8;  // Turn on WS_EX_TOPMOST
            return cp;
        }
    }