【问题标题】:Close form not showing in application openforms关闭表单未显示在应用程序打开表单中
【发布时间】:2023-03-07 02:16:01
【问题描述】:

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

这很好,但我现在需要关闭表单,表单本身不会显示在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);

}

【问题讨论】:

    标签: c# winforms winapi user32


    【解决方案1】:

    是的,这不是唯一的不幸。例如,您还可以看到表单的 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;
            }
        }
    

    【讨论】:

    • 感谢您,测试表单似乎有效,只需使用电话系统实现测试 toast 表单,以确保表单在事件触发时关闭,然后我将标记为正确回答!
    最近更新 更多