2

私は完全にカスタムのウィンドウ コントロールに取り組んでおり、その最大化を処理するために、WindowProc 関数をオーバーライドし、自分自身で WM_GETMINMAXINFO メッセージを処理しています。

MINMAXINFO 構造体を入力してウィンドウ ハンドルに送信すると、完了です。

メインモニターでは問題なく動作しますが、セカンドモニターではウィンドウが大きすぎます..

私が理解していないのは、2 番目のモニターで最大化するときに送信する MINMAXINFO 構造体に正しいサイズ情報 (1920x1080) があることですが、一度最大化すると、ウィンドウは 2160x1100 のサイズで終了します。

何が起こっているのか誰にも分かりますか?

どうもありがとうございます。

4

3 に答える 3

1

@Karnalta - 私はしばらく前に似たようなことをしていました。私の古いブログ記事を見てください。上記のリンクにあるダウンロード可能なサンプルで、タスクバーとタスクバーの自動非表示について説明します。私のモニターは両方とも同じサイズなので、私にとっては完璧に機能しているように見えますが、試してみてください. おそらく最も関心のある 2 つの方法を次に示します。

private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
    MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
    IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

    if (monitorContainingApplication != System.IntPtr.Zero)
    {
        MONITORINFO monitorInfo = new MONITORINFO();
        GetMonitorInfo(monitorContainingApplication, monitorInfo);
        RECT rcWorkArea = monitorInfo.rcWork;
        RECT rcMonitorArea = monitorInfo.rcMonitor;
        mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
        mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
        mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
        mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
        mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x;                                                 //maximum drag X size for the window
        mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y;                                                 //maximum drag Y size for the window
        mmi.ptMinTrackSize.x = 800;                                                             //minimum drag X size for the window
        mmi.ptMinTrackSize.y = 600;                                                             //minimum drag Y size for the window
        mmi = AdjustWorkingAreaForAutoHide(monitorContainingApplication, mmi);                  //need to adjust sizing if taskbar is set to autohide
    }
    Marshal.StructureToPtr(mmi, lParam, true);
}

private static MINMAXINFO AdjustWorkingAreaForAutoHide(IntPtr monitorContainingApplication, MINMAXINFO mmi)
{
    IntPtr hwnd = FindWindow("Shell_TrayWnd", null);
    if (hwnd == null) return mmi;
    IntPtr monitorWithTaskbarOnIt = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
    if (!monitorContainingApplication.Equals(monitorWithTaskbarOnIt)) return mmi;
    APPBARDATA abd = new APPBARDATA();
    abd.cbSize = Marshal.SizeOf(abd);
    abd.hWnd = hwnd;
    SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref abd);
    int uEdge = GetEdge(abd.rc);
    bool autoHide = System.Convert.ToBoolean(SHAppBarMessage((int)ABMsg.ABM_GETSTATE, ref abd));

    if (!autoHide) return mmi;

    switch (uEdge)
    {
        case (int)ABEdge.ABE_LEFT:
            mmi.ptMaxPosition.x += 2;
            mmi.ptMaxTrackSize.x -= 2;
            mmi.ptMaxSize.x -= 2;
            break;
        case (int)ABEdge.ABE_RIGHT:
            mmi.ptMaxSize.x -= 2;
            mmi.ptMaxTrackSize.x -= 2;
            break;
        case (int)ABEdge.ABE_TOP:
            mmi.ptMaxPosition.y += 2;
            mmi.ptMaxTrackSize.y -= 2;
            mmi.ptMaxSize.y -= 2;
            break;
        case (int)ABEdge.ABE_BOTTOM:
            mmi.ptMaxSize.y -= 2;
            mmi.ptMaxTrackSize.y -= 2;
            break;
        default:
            return mmi;
    }
    return mmi;
}
于 2013-03-01T20:40:29.347 に答える
0

セカンドモニターのサイズに基づいてサイズを提供しているようです。WM_GETMINMAXINFOのドキュメントには、ウィンドウが別の解像度の別のモニターに表示される場合でも、幅/高さはプライマリ モニターのサイズに基づいて表現されると記載されています。

于 2013-03-04T14:48:42.157 に答える
0

WindowState = System.Windows.WindowState.Maximized;win32 イベントを使用する代わりに、WPF に ( を使用して) ウィンドウを最大化し、必要なサイズに合わせてウィンドウ コンテンツ テンプレートを変更する方がおそらく簡単でしょう。

たとえば、ウィンドウのコンテンツをグリッドにカプセル化し、このグリッドにマージンを設定できます。最後に、ウィンドウの背景プロパティ (存在する場合) をグリッドに移動し、ウィンドウの背景に透明な色を設定します。

于 2013-02-28T12:40:04.750 に答える