wndprocでのaerosnapメッセージの処理
-
26-10-2019 - |
質問
私のc#.net 4アプリケーションでは、私は使用します WndProc
フル画面との間でアプリケーションのサイズ変更を主に扱うメッセージを処理するため。
今、私はただ取り扱っています SC_MAXIMIZE
と WM_NCLBUTTONDBLCLK
ウィンドウが最大化された状態に変更されているかどうかを判断するために(私はwndprocを処理する必要がないことを知っています SC_MAXIMIZE
, 、 しかし Form_Resize
aのために発砲しなかったようです WM_NCLBUTTONDBLCLK
メッセージアプリケーションのタイトルバーをダブルクリックするとき。
今、私はAeroが画面の上部にスナップして画面の上部にスナップして最大化することに気づきました。上記のメッセージはどちらも投稿されていないため、Aero Snapを介してウィンドウが最大化されると特定のロジックが適用されません。ウィンドウが右または左ではなく画面の上部にスナップされている場合、または最大の位置からウィンドウが非表示になっている場合にのみ、メッセージを処理したいと思います。
エアロスナップに関連するウィンドウメッセージは見つかりませんでした。これらのメッセージの参照を知っている人はいますか?
解決
ここには特別なメッセージはないと思います。エアロはおそらくプレーンWin32 APIを使用しているだけです - showwindow(sw_maximize) 同様です。
sc_メッセージを使用してuderstandすることは、それらが メニューからのリクエスト ウィンドウにサイズを変更/復元するように依頼しますが、それ自体を変更しますが、それがウィンドウのサイズを変更するための唯一のメカニズムではありません。おそらく起こっているのは、ウィンドウが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;
}