/************************************************************************************* Extended WPF Toolkit Copyright (C) 2007-2013 Xceed Software Inc. This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license For more features, controls, and fast professional support, pick up the Plus Edition at http://xceed.com/wpf_toolkit Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids ***********************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Windows; namespace Xceed.Wpf.AvalonDock { internal static class Win32Helper { [DllImport("user32.dll", EntryPoint = "CreateWindowEx", CharSet = CharSet.Unicode)] internal static extern IntPtr CreateWindowEx(int dwExStyle, string lpszClassName, string lpszWindowName, int style, int x, int y, int width, int height, IntPtr hwndParent, IntPtr hMenu, IntPtr hInst, [MarshalAs(UnmanagedType.AsAny)] object pvParam); internal const int WS_CHILD = 0x40000000, WS_VISIBLE = 0x10000000, WS_VSCROLL = 0x00200000, WS_BORDER = 0x00800000, WS_CLIPSIBLINGS = 0x04000000, WS_CLIPCHILDREN = 0x02000000, WS_TABSTOP = 0x00010000, WS_GROUP = 0x00020000; /// /// SetWindowPos Flags /// [Flags()] internal enum SetWindowPosFlags : uint { /// If the calling thread and the thread that owns the window are attached to different input queues, /// the system posts the request to the thread that owns the window. This prevents the calling thread from /// blocking its execution while other threads process the request. /// SWP_ASYNCWINDOWPOS SynchronousWindowPosition = 0x4000, /// Prevents generation of the WM_SYNCPAINT message. /// SWP_DEFERERASE DeferErase = 0x2000, /// Draws a frame (defined in the window's class description) around the window. /// SWP_DRAWFRAME DrawFrame = 0x0020, /// Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to /// the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE /// is sent only when the window's size is being changed. /// SWP_FRAMECHANGED FrameChanged = 0x0020, /// Hides the window. /// SWP_HIDEWINDOW HideWindow = 0x0080, /// Does not activate the window. If this flag is not set, the window is activated and moved to the /// top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter /// parameter). /// SWP_NOACTIVATE DoNotActivate = 0x0010, /// Discards the entire contents of the client area. If this flag is not specified, the valid /// contents of the client area are saved and copied back into the client area after the window is sized or /// repositioned. /// SWP_NOCOPYBITS DoNotCopyBits = 0x0100, /// Retains the current position (ignores X and Y parameters). /// SWP_NOMOVE IgnoreMove = 0x0002, /// Does not change the owner window's position in the Z order. /// SWP_NOOWNERZORDER DoNotChangeOwnerZOrder = 0x0200, /// Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to /// the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent /// window uncovered as a result of the window being moved. When this flag is set, the application must /// explicitly invalidate or redraw any parts of the window and parent window that need redrawing. /// SWP_NOREDRAW DoNotRedraw = 0x0008, /// Same as the SWP_NOOWNERZORDER flag. /// SWP_NOREPOSITION DoNotReposition = 0x0200, /// Prevents the window from receiving the WM_WINDOWPOSCHANGING message. /// SWP_NOSENDCHANGING DoNotSendChangingEvent = 0x0400, /// Retains the current size (ignores the cx and cy parameters). /// SWP_NOSIZE IgnoreResize = 0x0001, /// Retains the current Z order (ignores the hWndInsertAfter parameter). /// SWP_NOZORDER IgnoreZOrder = 0x0004, /// Displays the window. /// SWP_SHOWWINDOW ShowWindow = 0x0040, } /// /// Special window handles /// internal static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); internal static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); internal static readonly IntPtr HWND_TOP = new IntPtr(0); internal static readonly IntPtr HWND_BOTTOM = new IntPtr(1); [StructLayout(LayoutKind.Sequential)] internal class WINDOWPOS { public IntPtr hwnd; public IntPtr hwndInsertAfter; public int x; public int y; public int cx; public int cy; public int flags; }; [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags); [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] internal static extern bool IsChild(IntPtr hWndParent, IntPtr hwnd); [DllImport("user32.dll")] internal static extern IntPtr SetFocus(IntPtr hWnd); internal const int WM_WINDOWPOSCHANGED = 0x0047; internal const int WM_WINDOWPOSCHANGING = 0x0046; internal const int WM_NCMOUSEMOVE = 0xa0; internal const int WM_NCLBUTTONDOWN = 0xA1; internal const int WM_NCLBUTTONUP = 0xA2; internal const int WM_NCLBUTTONDBLCLK = 0xA3; internal const int WM_NCRBUTTONDOWN = 0xA4; internal const int WM_NCRBUTTONUP = 0xA5; internal const int WM_CAPTURECHANGED = 0x0215; internal const int WM_EXITSIZEMOVE = 0x0232; internal const int WM_ENTERSIZEMOVE = 0x0231; internal const int WM_MOVE = 0x0003; internal const int WM_MOVING = 0x0216; internal const int WM_KILLFOCUS = 0x0008; internal const int WM_SETFOCUS = 0x0007; internal const int WM_ACTIVATE = 0x0006; internal const int WM_NCHITTEST = 0x0084; internal const int WM_INITMENUPOPUP = 0x0117; internal const int WM_KEYDOWN = 0x0100; internal const int WM_KEYUP = 0x0101; internal const int WA_INACTIVE = 0x0000; internal const int WM_SYSCOMMAND = 0x0112; // These are the wParam of WM_SYSCOMMAND internal const int SC_MAXIMIZE = 0xF030; internal const int SC_RESTORE = 0xF120; internal const int WM_CREATE = 0x0001; [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr SetActiveWindow(IntPtr hWnd); [DllImport("user32.dll", EntryPoint = "DestroyWindow", CharSet = CharSet.Unicode)] internal static extern bool DestroyWindow(IntPtr hwnd); internal const int HT_CAPTION = 0x2; [DllImportAttribute("user32.dll")] internal static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImportAttribute("user32.dll")] internal static extern int PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); [DllImport("user32.dll")] internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); // Hook Types public enum HookType : int { WH_JOURNALRECORD = 0, WH_JOURNALPLAYBACK = 1, WH_KEYBOARD = 2, WH_GETMESSAGE = 3, WH_CALLWNDPROC = 4, WH_CBT = 5, WH_SYSMSGFILTER = 6, WH_MOUSE = 7, WH_HARDWARE = 8, WH_DEBUG = 9, WH_SHELL = 10, WH_FOREGROUNDIDLE = 11, WH_CALLWNDPROCRET = 12, WH_KEYBOARD_LL = 13, WH_MOUSE_LL = 14 } public const int HCBT_SETFOCUS = 9; public const int HCBT_ACTIVATE = 5; [DllImport("kernel32.dll")] public static extern uint GetCurrentThreadId(); public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] public static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadID); [DllImport("user32.dll")] public static extern int UnhookWindowsHookEx(IntPtr hhook); [DllImport("user32.dll")] public static extern int CallNextHookEx(IntPtr hhook, int code, IntPtr wParam, IntPtr lParam); [Serializable, StructLayout(LayoutKind.Sequential)] internal struct RECT { public int Left; public int Top; public int Right; public int Bottom; public RECT(int left_, int top_, int right_, int bottom_) { Left = left_; Top = top_; Right = right_; Bottom = bottom_; } public int Height { get { return Bottom - Top; } } public int Width { get { return Right - Left; } } public Size Size { get { return new Size(Width, Height); } } public Point Location { get { return new Point(Left, Top); } } // Handy method for converting to a System.Drawing.Rectangle public Rect ToRectangle() { return new Rect(Left, Top, Right, Bottom); } public static RECT FromRectangle(Rect rectangle) { return new Rect(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom); } public override int GetHashCode() { return Left ^ ((Top << 13) | (Top >> 0x13)) ^ ((Width << 0x1a) | (Width >> 6)) ^ ((Height << 7) | (Height >> 0x19)); } #region Operator overloads public static implicit operator Rect(RECT rect) { return rect.ToRectangle(); } public static implicit operator RECT(Rect rect) { return FromRectangle(rect); } #endregion } internal static RECT GetClientRect(IntPtr hWnd) { RECT result = new RECT(); GetClientRect(hWnd, out result); return result; } internal static RECT GetWindowRect(IntPtr hWnd) { RECT result = new RECT(); GetWindowRect(hWnd, out result); return result; } [DllImport("user32.dll")] internal static extern IntPtr GetTopWindow(IntPtr hWnd); internal const uint GW_HWNDNEXT = 2; internal const uint GW_HWNDPREV = 3; [DllImport("user32.dll", SetLastError = true)] internal static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd); internal enum GetWindow_Cmd : uint { GW_HWNDFIRST = 0, GW_HWNDLAST = 1, GW_HWNDNEXT = 2, GW_HWNDPREV = 3, GW_OWNER = 4, GW_CHILD = 5, GW_ENABLEDPOPUP = 6 } internal static int MakeLParam(int LoWord, int HiWord) { //System.Diagnostics.Trace.WriteLine("LoWord: " + LoWord2(((HiWord << 16) | //(LoWord & 0xffff)))); return (int) ((HiWord << 16) | (LoWord & 0xffff)); } internal const int WM_MOUSEMOVE = 0x200; internal const int WM_LBUTTONDOWN = 0x201; internal const int WM_LBUTTONUP = 0x202; internal const int WM_LBUTTONDBLCLK = 0x203; internal const int WM_RBUTTONDOWN = 0x204; internal const int WM_RBUTTONUP = 0x205; internal const int WM_RBUTTONDBLCLK = 0x206; internal const int WM_MBUTTONDOWN = 0x207; internal const int WM_MBUTTONUP = 0x208; internal const int WM_MBUTTONDBLCLK = 0x209; internal const int WM_MOUSEWHEEL = 0x20A; internal const int WM_MOUSEHWHEEL = 0x20E; [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetCursorPos(ref Win32Point pt); [StructLayout(LayoutKind.Sequential)] internal struct Win32Point { public Int32 X; public Int32 Y; }; internal static Point GetMousePosition() { Win32Point w32Mouse = new Win32Point(); GetCursorPos(ref w32Mouse); return new Point(w32Mouse.X, w32Mouse.Y); } [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool IsWindowEnabled(IntPtr hWnd); [DllImport("user32.dll")] internal static extern IntPtr GetFocus(); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool BringWindowToTop(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true)] internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] internal static extern IntPtr GetParent(IntPtr hWnd); /// /// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory. /// /// A handle to the window and, indirectly, the class to which the window belongs.. /// The zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of the following values: GWL_EXSTYLE, GWL_HINSTANCE, GWL_ID, GWL_STYLE, GWL_USERDATA, GWL_WNDPROC /// The replacement value. /// If the function succeeds, the return value is the previous value of the specified 32-bit integer. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. [DllImport("user32.dll")] static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll", SetLastError = true)] static extern int GetWindowLong(IntPtr hWnd, int nIndex); public static void SetOwner(IntPtr childHandle, IntPtr ownerHandle) { SetWindowLong( childHandle, -8, // GWL_HWNDPARENT ownerHandle.ToInt32()); } public static IntPtr GetOwner(IntPtr childHandle) { return new IntPtr(GetWindowLong(childHandle, -8)); } //Monitor Patch #13440 /// /// The MonitorFromRect function retrieves a handle to the display monitor that /// has the largest area of intersection with a specified rectangle. /// /// Pointer to a RECT structure that specifies the rectangle of interest in /// virtual-screen coordinates /// Determines the function's return value if the rectangle does not intersect /// any display monitor /// /// If the rectangle intersects one or more display monitor rectangles, the return value /// is an HMONITOR handle to the display monitor that has the largest area of intersection with the rectangle. /// If the rectangle does not intersect a display monitor, the return value depends on the value of dwFlags. /// [DllImport("user32.dll")] public static extern IntPtr MonitorFromRect([In] ref RECT lprc, uint dwFlags); /// /// The MonitorFromWindow function retrieves a handle to the display monitor that has the largest area of intersection with the bounding rectangle of a specified window. /// /// A handle to the window of interest. /// Determines the function's return value if the window does not intersect any display monitor. /// If the window intersects one or more display monitor rectangles, the return value is an HMONITOR handle to the display monitor that has the largest area of intersection with the window. /// If the window does not intersect a display monitor, the return value depends on the value of dwFlags. /// [DllImport("user32.dll")] public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags); /// /// The MONITORINFO structure contains information about a display monitor. /// [StructLayout(LayoutKind.Sequential)] public class MonitorInfo { /// /// The size of the structure, in bytes. /// public int Size = Marshal.SizeOf(typeof(MonitorInfo)); /// /// A RECT structure that specifies the display monitor rectangle, expressed /// in virtual-screen coordinates. /// Note that if the monitor is not the primary display monitor, /// some of the rectangle's coordinates may be negative values. /// public RECT Monitor; /// /// A RECT structure that specifies the work area rectangle of the display monitor, /// expressed in virtual-screen coordinates. Note that if the monitor is not the primary /// display monitor, some of the rectangle's coordinates may be negative values. /// public RECT Work; /// /// A set of flags that represent attributes of the display monitor. /// public uint Flags; } /// /// The GetMonitorInfo function retrieves information about a display monitor. /// /// Handle to the display monitor of interest. /// Pointer to a MONITORINFO or MONITORINFOEX structure that receives /// information about the specified display monitor /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetMonitorInfo(IntPtr hMonitor, [In, Out] MonitorInfo lpmi); } }