Вопрос

В моем приложении C# .net 4 я использую WndProc Для обработки некоторых сообщений в основном касается изменения размера приложения на полный экран.

Прямо сейчас я просто обращаюсь SC_MAXIMIZE а также WM_NCLBUTTONDBLCLK Чтобы определить, изменяется ли окно до максимизированного состояния или из SC_MAXIMIZE, но Form_Resize казалось, не стрелял в WM_NCLBUTTONDBLCLK Сообщение, когда я дважды щелкнул на строку заголовка приложения.

Now I noticed that if I Aero Snap the window to the top of the screen to maximize it, neither of the above messages are posted so certain logic is not applied when the window is maximized via Aero Snap. Я хочу обрабатывать сообщение только в том случае, если окно срезано в верхнюю часть экрана, а не к праву или влево, или если окно не подходит из максимизированного положения.

Я не мог найти ни одного из оконных сообщений, связанных с Aero Snap. Кто -нибудь знает какие -либо ссылки на эти сообщения?

Это было полезно?

Решение

Я предполагаю, что здесь нет особых сообщений; Aero, вероятно, просто использует простой API Win32 - ShowWindow (SW_MAXIMIZE) и аналогично.

Что касается сообщений SC_, так это то, что это Запросы из меню Запрашивая окно изменить размер/восстановление/и т. Д., но это не единственный механизм изменения размера окон. Вероятно, происходит то, что когда окно становится sc_maximize, defwndproc реализует это, вызывая Showwindow (SW_Maximize).

Лучше всего слушать Wm_size Сообщение, которое получает окно, независимо от того, что вызвало изменение размера: системное меню, API или другие средства. В частности, LPARAM сообщит вам, было ли максимизировано окно (size_maximized) или восстановлен (size_restored).

Другие советы

Вот код для обработки Wm_windowposchanging Сообщение для максимизации вместо Wm_size сообщение. Благодаря 20 или более вопросам, чтобы мне пришлось читать, чтобы найти все биты, чтобы собрать их вместе и собрать их. Это решает проблемы, которые у меня были с несколькими мониторами, использующими разные решения.

//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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top