Frage

In meiner C# .NET 4 -Anwendung verwende ich WndProc Um einige Nachrichten zu verarbeiten, die sich hauptsächlich mit der Änderung der Anwendung von und vom Vollbildmodus befassen.

Im Moment handle ich nur SC_MAXIMIZE und WM_NCLBUTTONDBLCLK Um festzustellen, ob das Fenster in oder von einem maximierten Zustand geändert wird (ich weiß, ich brauche keine WndProc, um zu handhaben SC_MAXIMIZE, aber Form_Resize schien nicht für a zu feuern WM_NCLBUTTONDBLCLK Nachricht Wenn ich auf die Titelleiste der Anwendung doppelklicke.

Jetzt bemerkte ich, dass, wenn ich das Fenster zum oberen Rand des Bildschirms schnappe, um es zu maximieren, keine der oben genannten Nachrichten veröffentlicht wird, sodass die Logik nicht angewendet wird, wenn das Fenster über Aero Snap maximiert wird. Ich möchte die Nachricht nur verarbeiten, wenn das Fenster an die Oberseite des Bildschirms und nicht nach rechts oder links geschnappt wird oder wenn ein Fenster von der maximierten Position entnommen wird.

Ich konnte keine der Fenstermeldungen finden, die sich auf Aero Snap beziehen. Kennt jemand irgendwelche Referenzen für diese Nachrichten?

War es hilfreich?

Lösung

Ich vermute, hier gibt es keine besonderen Nachrichten. Aero verwendet wahrscheinlich nur die einfachen Win32 -APIs - ShowWindow (sw_maximize) und ähnlich.

Die Sache, mit den SC_ -Nachrichten zu verstanden, ist, dass dies sind Anfragen aus einem Menü Fragen Sie das Fenster, um die Größe/Wiederherstellung/etc selbst zu ändern, aber dies ist nicht der einzige Mechanismus, um die Größe des Fensters zu ändern. Was wahrscheinlich passiert, ist, dass das DefwndProc dies, wenn ein Fenster sc_maximize erhält, dies implementiert, indem er ShowWindow (SW_MAXIMIMISE) aufruft.

Ihr Bestes ist es, dem zu hören Wm_size Nachricht, die das Fenster empfängt, unabhängig davon, was die Größenänderung ausgelöst hat: Systemmenü, API oder andere Mittel. Insbesondere das LPARAM lässt Sie wissen, ob das Fenster maximiert wurde (size_maximized) oder restauriert (size_restored).

Andere Tipps

Hier ist der Code für die Handhabung Wm_windowposchanging Nachricht für maximieren statt maximieren Wm_size Botschaft. Vielen Dank an die 20 oder mehr Fragen zu, damit ich lesen musste, um alle Teile zu finden, um sie zusammenzustellen und zum Laufen zu bringen. Dies befasst sich mit den Problemen, die ich mit mehreren Monitoren mit unterschiedlichen Auflösungen hatte.

//register the hook
public static void WindowInitialized(Window window)
{
    IntPtr handle = (new WindowInteropHelper(window)).Handle;
    var hwndSource = HwndSource.FromHwnd(handle);
    if (hwndSource != null) 
    {
        hwndSource.AddHook(WindowProc);
    }
}

//the important bit
private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case 0x0046: //WINDOWPOSCHANGING
            var winPos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));
            var monitorInfo = new MONITORINFO();
            IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MonitorDefaultToNearest);
            GetMonitorInfo(monitorContainingApplication, monitorInfo);
            RECT rcWorkArea = monitorInfo.rcWork;
            //check for a framechange - but ignore initial draw. x,y is top left of current monitor so must be a maximise
            if (((winPos.flags & SWP_FRAMECHANGED) == SWP_FRAMECHANGED) && (winPos.flags & SWP_NOSIZE) != SWP_NOSIZE && winPos.x == rcWorkArea.left && winPos.y == rcWorkArea.top)
            {
                //set max size to the size of the *current* monitor
                var width = Math.Abs(rcWorkArea.right - rcWorkArea.left);
                var height = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
                winPos.cx = width;
                winPos.cy = height;
                Marshal.StructureToPtr(winPos, lParam, true);
                handled = true;
            }                       
            break;
    }
    return (IntPtr)0;
}


//all the helpers for dealing with this COM crap
[DllImport("user32")]
internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);

[DllImport("user32")]
internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

private const int MonitorDefaultToNearest = 0x00000002;

[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
    public IntPtr hwnd;
    public IntPtr hwndInsertAfter;
    public int x;
    public int y;
    public int cx;
    public int cy;
    public int flags;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MONITORINFO
{
    public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
    public RECT rcMonitor;
    public RECT rcWork;
    public int dwFlags;
}

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top