2012-02-17 44 views
5

在我的C#.NET 4應用程序中,我使用WndProc來處理一些消息,主要是處理全屏應用程序的大小調整。在WndProc中處理AeroSnap消息

現在我只是處理SC_MAXIMIZEWM_NCLBUTTONDBLCLK來確定窗口調整大小或從最大化狀態(我知道我不需要的WndProc處理SC_MAXIMIZE,但Form_Resize似乎沒有火了WM_NCLBUTTONDBLCLK消息當我雙擊應用程序的標題欄

現在我注意到,如果我Aero將窗口捕捉到屏幕頂部以最大化它,上面的消息都不會發布,因此不應用某些邏輯當窗口通過Aero Snap被最大化時,我只想處理消息,如果窗口被捕捉到屏幕的頂部而不是右邊或左邊,或者窗口從最大化的p osition。

我找不到任何與Aero Snap相關的窗口消息。有沒有人知道這些消息的任何參考?

+0

我也想知道這個以及...我從來沒有能夠弄清楚,但是。 – aboveyou00 2012-02-17 01:55:08

回答

7

我猜這裏沒有任何特別的信息; Aero可能只是使用簡單的Win32 APIs-ShowWindow(SW_MAXIMIZE)和類似的。

與SC_消息uderstand的事情是那些從菜單請求,要求窗口調整/恢復/等本身,而不是改變窗口大小的唯一機制。可能發生的事情是,當窗口獲得SC_MAXIMIZE時,DefWndProc通過調用ShowWindow(SW_MAXIMIZE)來實現此目的。

無論觸發大小改變的是什麼:系統菜單,API或其他方式,您最好聽聽窗口接收的WM_SIZE消息。特別是,lParam會讓你知道窗口是最大化(SIZE_MAXIMIZED)還是恢復(SIZE_RESTORED)。

+3

這是正確的。 Aero Snap沒有發送特別通知。它使用標準的'WM_MOVING' /'WM_MOVE'和'WM_SIZING' /'WM_SIZE'消息。如果您在不調用「DefWindowProc」的情況下處理這些文件,Aero Snap將無法用於您的窗口。是的,你可以聽'WM_SIZE',但是你最好使用['WM_WINDOWPOSCHANGED'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms632652.aspx) 。這是一個「新」功能,在Windows 3.1中引入。 :-) [相關閱讀](http://blogs.msdn.com/b/oldnewthing/archive/2008/01/15/7113860.aspx)。 – 2012-02-17 02:35:56

+1

POSCHANGED的捕捉是你爲任何*移動/大小改變而得到它,包括當窗口在「捕捉」之前移動時,所以你需要做更多的過濾。而且我不知道你是否可以從其參數中確定最大化的「快照」 - 沒有明顯的「窗口最大化」指標。用WM_SIZE,檢查lParam,你就完成了! – BrendanMcK 2012-02-17 02:52:53

+0

是的,你需要做一些過濾。這基本上是不可避免的,您必須過濾「WM_SIZE」以確保您只處理由Aero Snap啓動的調整大小事件。關鍵是你的所有處理代碼都在一個地方。我真的沒有看到WM_WINDOWPOSCHANGED消息處理程序中的'switch'語句和處理'WM_MOVE','WM_SIZE'等的窗口過程內的'switch'語句之間的區別。我認爲擁有巨大的權力會帶來很大的責任。任何一個都會工作。 – 2012-02-17 02:54:52

2

以下是處理WM_WINDOWPOSCHANGING消息的代碼,用於最大化消息而不是WM_SIZE消息。感謝20個或更多關於SO的問題,我必須閱讀所有這些問題才能將它們放在一起並使其工作。這解決了我使用不同分辨率的多臺顯示器時遇到的問題。

//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; 
} 
+0

Upvoted純粹是爲了您的評論「處理這個C​​OM廢話的所有幫手」... – 2017-11-01 11:40:05