c# - 底层表单消失但仅当对话框显示时

标签 c# winforms vb6 com-interop z-order

这与通过互操作显示 C# 表单的 VB6 应用程序相关。

C# 表单中的事件导致显示 VB6 应用程序表单之一。

通常,当隐藏此 VB6 表单 (Form.Hide) 时,底层 C# 表单会显示在前面。

但是,如果 VB6 窗体在其生命周期内导致 MsgBox 显示,那么当 VB6 窗体隐藏时,底层 C# 窗体将不会位于前面。

为什么会发生这种情况?就像 MsgBox 正在更改表单的 Z 顺序。

最佳答案

“如何在隐藏 VB6 后显示 C# 窗体?我必须使用窗口句柄吗?”

假设您同意孤立的消息框保持打开状态。当 VB6 窗体隐藏时,您需要触发一个事件来获取窗口句柄:

public static int FindWindow(string windowName, bool wait)
{
    int hWnd = FindWindow(null, windowName);
    while (wait && hWnd == 0)
    {
         System.Threading.Thread.Sleep(500);
         hWnd = FindWindow(null, windowName);
    }

    return hWnd;
}

然后将 C# 窗口置于顶部:

[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

// When you don't want the ProcessId, use this overload and pass IntPtr.Zero for the second parameter
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();

/// <summary>The GetForegroundWindow function returns a handle to the foreground window.</summary>
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(IntPtr hWnd);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(HandleRef hWnd);

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

private static void ForceForegroundWindow(IntPtr hWnd)
{
    uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
    uint appThread = GetCurrentThreadId();
    const uint SW_SHOW = 5;

    if (foreThread != appThread)
    {
        AttachThreadInput(foreThread, appThread, true);
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);
        AttachThreadInput(foreThread, appThread, false);
    }
    else
    {
        BringWindowToTop(hWnd);
        ShowWindow(hWnd, SW_SHOW);
    }
}

引用号:SetForegroundWindow Win32-API not always works on Windows-7

关于c# - 底层表单消失但仅当对话框显示时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12544436/

相关文章:

vb6 - VB6:为什么Picturebox.Print()从对象目录中隐藏?

c# - 模拟静态方法 Activator.CreateInstance 以返回另一个类的模拟

c# - 生成方法调用的代码。生成的 C# 代码显示的声明局部变量比 IL 代码中实际存在的变量多?

c# - 如何在 C# 中从 sql server 运行代码

c# - Excel 之上的 Windows 窗体

mysql - Vb6 记录更新错误

c# - 强制 C# 转换为泛型

c# - 具有不同方向的 WPF 虚拟化 TreeView 不虚拟化?

c# - winform控件中文本中的一个粗体字

string - 从VB6中的字符串中删除字符