2

これは、相互運用機能を介して C# フォームを表示する VB6 アプリに関連しています。

C# フォームのイベントにより、VB6 アプリ フォームの 1 つが表示されます。

通常、この VB6 フォームを非表示 ( Form.Hide) にすると、基になる C# フォームが前面に表示されます。

しかし、VB6 フォームが存続期間中にMsgBox表示されるようになった場合、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);
    }
}

参照:SetForegroundWindowWin32-APIはWindows-7で常に機能するとは限りません

于 2012-09-23T04:11:19.347 に答える
1

このスレッドの最後の回答に従って、NativeWindowクラスを使用して動作するようにしました。 -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 に答える