2

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

C# 窗体中的事件会导致显示其中一个 VB6 应用程序窗体。

通常,当这个 VB6 表单被隐藏(Form.Hide)时,底层的 C# 表单被带到前面。

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

为什么会这样?就像MsgBox正在改变表格的 Z 顺序一样。

4

2 回答 2

1

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

假设您对孤立的 msgbox 保持打开状态感到满意。当 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 并不总是适用于 Windows-7

于 2012-09-23T04:11:19.347 回答
1

我通过使用NativeWindow类使其工作,遵循此线程中的最后一个答案:http: //social.msdn.microsoft.com/Forums/en-US/2692df26-317c-4415-816b-d08fe6854df8/vbnet-vb6 -win32-api-problems?forum=vbinterop

该代码用于FindWindowEx获取VB6窗口的句柄,这是不必要的,因为您可以简单地将VB6窗口的句柄传递给.NET表单:

public void ShowDotNetForm(IntPtr hwndMain) 
{
    NativeWindow vb6Window = new NativeWindow();
    vb6Window.AssignHandle(hwndMain);
    f.Show(vb6Window);
}

表格中的代码VB6是:

dotNetObj.ShowDotNetForm Me.hWnd

传递窗口句柄从VB6更好,因为FindWindowEx需要您知道窗口标题的文本才能获取句柄。

于 2014-02-18T06:51:58.133 回答