private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { POINT lMousePosition; GetCursorPos(out lMousePosition); IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY); MONITORINFO lPrimaryScreenInfo = new MONITORINFO(); if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false) { return; } IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST); MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); if (lPrimaryScreen.Equals(lCurrentScreen)) { lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left; lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top; lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left; lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top; } else { lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left; lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top; lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left; lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top; } Marshal.StructureToPtr(lMmi, lParam, true); }
private void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor int MONITOR_DEFAULTTONEAREST =0x00000002; IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); // Convert pixel sizes based on current DPI settings. // Window.MinHeight/MinWidth are 1/96th of an inch. PresentationSource presentationSource = PresentationSource.FromVisual(this); if (presentationSource != null) { if (presentationSource.CompositionTarget != null) { Point minSize = presentationSource.CompositionTarget.TransformToDevice.Transform(new Point(MinWidth, MinHeight)); mmi.ptMinTrackSize.x = (int)minSize.X; mmi.ptMinTrackSize.y = (int)minSize.Y; } } } Marshal.StructureToPtr(mmi, lParam, true); }
internal static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area // of the correct monitor. Int32 MONITOR_DEFAULTTONEAREST = 0x00000002; IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.m_rcWork; RECT rcMonitorArea = monitorInfo.m_rcMonitor; mmi.m_ptMaxPosition.m_x = Math.Abs(rcWorkArea.m_left - rcMonitorArea.m_left); mmi.m_ptMaxPosition.m_y = Math.Abs(rcWorkArea.m_top - rcMonitorArea.m_top); mmi.m_ptMaxSize.m_x = Math.Abs(rcWorkArea.m_right - rcWorkArea.m_left); mmi.m_ptMaxSize.m_y = Math.Abs(rcWorkArea.m_bottom - rcWorkArea.m_top); } Marshal.StructureToPtr(mmi, lParam, true); }
private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); int MONITOR_DEFAULTTONEAREST = 0x00000002; IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); } Marshal.StructureToPtr(mmi, lParam, true); }
private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { var structure = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); var hMonitor = MonitorFromWindow(hwnd, 2); if (hMonitor != IntPtr.Zero) { var lpmi = new MONITORINFO(); GetMonitorInfo(hMonitor, lpmi); RECT rcWork = lpmi.rcWork; RECT rcMonitor = lpmi.rcMonitor; structure.ptMaxPosition.x = Math.Abs((int)(rcWork.left - rcMonitor.left)); structure.ptMaxPosition.y = Math.Abs((int)(rcWork.top - rcMonitor.top)); structure.ptMaxSize.x = Math.Abs((int)(rcWork.right - rcWork.left)); structure.ptMaxSize.y = Math.Abs((int)(rcWork.bottom - rcWork.top)); structure.ptMinTrackSize.x = (int)Application.Current.MainWindow.MinWidth; structure.ptMinTrackSize.y = (int)Application.Current.MainWindow.MinHeight; } Marshal.StructureToPtr(structure, lParam, true); }
private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { var mmi = (MINMAXINFO) Marshal.PtrToStructure(lParam, typeof (MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor var MONITOR_DEFAULTTONEAREST = 0x00000002; var monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { var monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); var rcWorkArea = monitorInfo.rcWork; var rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); } Marshal.StructureToPtr(mmi, lParam, true); }
public static extern int GetMonitorInfo(IntPtr hNonitor, ref MONITORINFO lpmi);
private static void GetActualScreenData(ABEdge edge, Window appbarWindow, ref int leftOffset, ref int topOffset, ref int actualScreenWidth, ref int actualScreenHeight) { IntPtr handle = new WindowInteropHelper(appbarWindow).Handle; IntPtr monitorHandle = MonitorFromWindow(handle, MONITOR_DEFAULTTONEAREST); MONITORINFO mi = new MONITORINFO(); mi.cbSize = Marshal.SizeOf(mi); if (GetMonitorInfo(monitorHandle, ref mi)) { if (mi.dwFlags == MONITORINFOF_PRIMARY) { return; } leftOffset = mi.rcWork.left; topOffset = mi.rcWork.top; actualScreenWidth = mi.rcWork.right - leftOffset; actualScreenHeight = mi.rcWork.bottom - mi.rcWork.top; } }
public static Monitor GetMonitor(IntPtr hMonitor) { MONITORINFO _info = new MONITORINFO(); _info.cbSize = Marshal.SizeOf(_info); NativeMethods.GetMonitorInfo(hMonitor, ref _info); uint _dpiX = Monitor.DPICONST; uint _dpiY = Monitor.DPICONST; if (OS.SupportDPI) { NativeMethods.GetDpiForMonitor(hMonitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out _dpiX, out _dpiY); } return new Monitor() { Size = _info.Size, WorkArea = _info.WorkArea, DPIx = _dpiX, DPIy = _dpiY, IsPrimary = _info.IsPrimary }; }
public static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { // Get the MINMAXINFO structure from memory location given by lParam MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Get the monitor that overlaps the window or the nearest IntPtr monitor = MonitorFromWindow(hwnd, (uint)MonitorDefaults.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { // Get monitor information MONITORINFO monitorInfo = new MONITORINFO(); monitorInfo.Size = Marshal.SizeOf(typeof(MONITORINFO)); GetMonitorInfo(monitor, ref monitorInfo); // The display monitor rectangle. // If the monitor is not the primary display monitor, // some of the rectangle's coordinates may be negative values RECT rcMonitorArea = monitorInfo.Monitor; // Get window information WINDOWINFO windowInfo = new WINDOWINFO(); windowInfo.Size = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO))); GetWindowInfo(hwnd, ref windowInfo); int borderWidth = (int)windowInfo.WindowBordersWidth; int borderHeight = (int)windowInfo.WindowBordersHeight; // Set the dimensions of the window in maximized state mmi.MaxPosition.X = -borderWidth; mmi.MaxPosition.Y = -borderHeight; mmi.MaxSize.X = rcMonitorArea.Right - rcMonitorArea.Left + 2 * borderWidth; mmi.MaxSize.Y = rcMonitorArea.Bottom - rcMonitorArea.Top + 2 * borderHeight; // Set minimum and maximum size // to the size of the window in maximized state mmi.MinTrackSize.X = mmi.MaxSize.X; mmi.MinTrackSize.Y = mmi.MaxSize.Y; mmi.MaxTrackSize.X = mmi.MaxSize.X; mmi.MaxTrackSize.Y = mmi.MaxSize.Y; } // Copy the structure to memory location specified by lParam. // This concludes processing of WM_GETMINMAXINFO. Marshal.StructureToPtr(mmi, lParam, true); }
public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO info);
private static extern bool GetMonitorInfo(IntPtr hmon, ref MONITORINFO mi);
/// <summary> /// 获得并设置窗体大小信息 /// </summary> private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); int MONITOR_DEFAULTTONEAREST = 0x00000002; System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != System.IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); // 这行如果不注释掉在多显示器情况下显示会有问题! // mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); // 可设置窗体的最小尺寸 // mmi.ptMinTrackSize.x = 300; // mmi.ptMinTrackSize.y = 200; } Marshal.StructureToPtr(mmi, lParam, true); }
internal static extern bool GetMonitorInfo([In] IntPtr hMonitor, [Out] MONITORINFO lpmi);
/*---------------------------------------------------------------------------------*/ public bool IsFullScreen(string[] classNamesExcluded) { if (m_hWnd == IntPtr.Zero) return false; // 컨트롤의 최상위 핸들을 얻어옵니다. IntPtr hWnd = GetAncestor(m_hWnd, GetAncestorFlags.GetRoot); if (hWnd == IntPtr.Zero) return false; // 클래스이름을 얻어옵니다. StringBuilder className = new StringBuilder(256); if (GetClassName(hWnd, className, className.Capacity) == 0) return false; // 제외목록에서 하나라도 해당되는지 확인. if (classNamesExcluded.Any((string s) => s == className.ToString())) return false; // 현재 컨트롤이 속하는 모니터의 사각영역을 얻어옵니다. RECT desktop; IntPtr monitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); if (monitor == IntPtr.Zero) { // 모니터를 찾을 수 없으면 현재 윈도우 화면의 핸들로 설정한다. IntPtr desktopWnd = GetDesktopWindow(); if (desktopWnd == IntPtr.Zero) return false; if (GetWindowRect(desktopWnd, out desktop) == false) return false; } else { MONITORINFO info = new MONITORINFO(); info.cbSize = Marshal.SizeOf(info); if (GetMonitorInfo(monitor, ref info) == false) return false; desktop = info.rcMonitor; } // 컨트롤의 작업영역을 알아낸다. RECT client; if (GetClientRect(hWnd, out client) == false) return false; // 컨트롤의 크기가 모니터 크기보다 작으면 전체화면이 아니다. if (client.Width < desktop.Width || client.Height < desktop.Height) return false; // 여기까지 도달했으면 전체화면이다. return true; }
private void _SetRoundingRegion(WINDOWPOS?wp) { const int MONITOR_DEFAULTTONEAREST = 0x00000002; // We're early - WPF hasn't necessarily updated the state of the window. // Need to query it ourselves. WINDOWPLACEMENT wpl = NativeMethods.GetWindowPlacement(_hwnd); if (wpl.showCmd == SW.SHOWMAXIMIZED) { int left; int top; if (wp.HasValue) { left = wp.Value.x; top = wp.Value.y; } else { Rect r = _GetWindowRect(); left = (int)r.Left; top = (int)r.Top; } IntPtr hMon = NativeMethods.MonitorFromWindow(_hwnd, MONITOR_DEFAULTTONEAREST); MONITORINFO mi = NativeMethods.GetMonitorInfo(hMon); RECT rcMax = mi.rcWork; // The location of maximized window takes into account the border that Windows was // going to remove, so we also need to consider it. rcMax.Offset(-left, -top); IntPtr hrgn = NativeMethods.CreateRectRgnIndirect(rcMax); NativeMethods.SetWindowRgn(_hwnd, hrgn, NativeMethods.IsWindowVisible(_hwnd)); } else { int width; int height; // Use the size if it's specified. if (null != wp && !Utility.IsFlagSet(wp.Value.flags, (int)SWP.NOSIZE)) { width = wp.Value.cx; height = wp.Value.cy; } else if (null != wp && (_lastRoundingState == _window.WindowState)) { return; } else { Rect r = _GetWindowRect(); width = (int)r.Width; height = (int)r.Height; } _lastRoundingState = _window.WindowState; IntPtr hrgn = IntPtr.Zero; if (RoundCorners && 0 != RoundCornersRadius) { Point radius = DpiHelper.LogicalPixelsToDevice(new Point(RoundCornersRadius, RoundCornersRadius)); hrgn = NativeMethods.CreateRoundRectRgn(0, 0, width, height, (int)radius.X, (int)radius.Y); } else { hrgn = NativeMethods.CreateRectRgn(0, 0, width, height); } NativeMethods.SetWindowRgn(_hwnd, hrgn, NativeMethods.IsWindowVisible(_hwnd)); } }
private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor int MONITOR_DEFAULTTONEAREST = 0x00000002; System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != System.IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); // 这行如果不注释掉在多显示器情况下显示会有问题! // mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); workAreaMaxHeight = mmi.ptMaxSize.y; //当窗口的任务栏自动隐藏时,最大化的时候最下边要留几个像素的空白,否则此窗口将屏幕铺满,则鼠标移到最下边时,任务栏无法自动弹出 if (rcWorkArea.Height == rcMonitorArea.Height) { mmi.ptMaxSize.y -= 2; } } Marshal.StructureToPtr(mmi, lParam, true); }
private void HandleMaximize() { this.borderThicknessChangeNotifier.RaiseValueChanged = false; var raiseValueChanged = this.topMostChangeNotifier.RaiseValueChanged; this.topMostChangeNotifier.RaiseValueChanged = false; var metroWindow = this.AssociatedObject as MetroWindow; var enableDWMDropShadow = this.EnableDWMDropShadow; if (metroWindow != null) { enableDWMDropShadow = metroWindow.GlowBrush == null && (metroWindow.EnableDWMDropShadow || this.EnableDWMDropShadow); } if (this.AssociatedObject.WindowState == WindowState.Maximized) { // remove window border, so we can move the window from top monitor position this.AssociatedObject.BorderThickness = new Thickness(0); var ignoreTaskBar = metroWindow != null && metroWindow.IgnoreTaskbarOnMaximize; if (this.handle != IntPtr.Zero) { this.windowChrome.ResizeBorderThickness = new Thickness(0); // WindowChrome handles the size false if the main monitor is lesser the monitor where the window is maximized // so set the window pos/size twice IntPtr monitor = UnsafeNativeMethods.MonitorFromWindow(this.handle, Constants.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { var monitorInfo = new MONITORINFO(); UnsafeNativeMethods.GetMonitorInfo(monitor, monitorInfo); if (ignoreTaskBar) { var x = monitorInfo.rcMonitor.left; var y = monitorInfo.rcMonitor.top; var cx = Math.Abs(monitorInfo.rcMonitor.right - x); var cy = Math.Abs(monitorInfo.rcMonitor.bottom - y); var trayHWND = Standard.NativeMethods.FindWindow("Shell_TrayWnd", null); if (this.isWindwos10OrHigher && trayHWND != IntPtr.Zero) { UnsafeNativeMethods.SetWindowPos(this.handle, trayHWND, x, y, cx, cy, 0x0040); Standard.NativeMethods.ShowWindow(this.handle, Standard.SW.HIDE); Standard.NativeMethods.ShowWindow(this.handle, Standard.SW.SHOW); } else { UnsafeNativeMethods.SetWindowPos(this.handle, new IntPtr(-2), x, y, cx, cy, 0x0040); } } else { var x = monitorInfo.rcWork.left; var y = monitorInfo.rcWork.top; var cx = Math.Abs(monitorInfo.rcWork.right - x); var cy = Math.Abs(monitorInfo.rcWork.bottom - y); UnsafeNativeMethods.SetWindowPos(this.handle, new IntPtr(-2), x, y, cx, cy, 0x0040); } } } } else { if (!enableDWMDropShadow) { this.AssociatedObject.BorderThickness = this.savedBorderThickness.GetValueOrDefault(new Thickness(0)); } var resizeBorderThickness = this.savedResizeBorderThickness.GetValueOrDefault(new Thickness(0)); if (this.windowChrome.ResizeBorderThickness != resizeBorderThickness) { this.windowChrome.ResizeBorderThickness = resizeBorderThickness; } // #2694 make sure the window is not on top after restoring window // this issue was introduced after fixing the windows 10 bug with the taskbar and a maximized window that ignores the taskbar RECT rect; if (UnsafeNativeMethods.GetWindowRect(this.handle, out rect)) { var left = rect.left; var top = rect.top; var width = rect.Width; var height = rect.Height; // #2780 Don't blindly set the Z-Order to HWWND_NOTOPMOST. If this window has an owner, set // the Z-Order to be after the owner. This keeps external dialogs appearing correctly above // their owner window even when owner window is maximized and ignoring taskbar. IntPtr hwndInsAfter = Constants.HWND_NOTOPMOST; if (this.AssociatedObject.Owner != null) { hwndInsAfter = new WindowInteropHelper(this.AssociatedObject.Owner).Handle; } UnsafeNativeMethods.SetWindowPos(this.handle, hwndInsAfter, left, top, width, height, 0x0040); } } // fix nasty TopMost bug // - set TopMost="True" // - start mahapps demo // - TopMost works // - maximize window and back to normal // - TopMost is gone // // Problem with minimize animation when window is maximized #1528 // 1. Activate another application (such as Google Chrome). // 2. Run the demo and maximize it. // 3. Minimize the demo by clicking on the taskbar button. // Note that the minimize animation in this case does actually run, but somehow the other // application (Google Chrome in this example) is instantly switched to being the top window, // and so blocking the animation view. this.AssociatedObject.Topmost = false; this.AssociatedObject.Topmost = this.AssociatedObject.WindowState == WindowState.Minimized || this.savedTopMost; this.borderThicknessChangeNotifier.RaiseValueChanged = true; this.topMostChangeNotifier.RaiseValueChanged = raiseValueChanged; }
public static extern bool GetMonitorInfo( IntPtr hMonitor, ref MONITORINFO lpmi);
protected static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_ENTERSIZEMOVE) { var win = (Window)HwndSource.FromHwnd(hwnd).RootVisual; var state = AcrylicWindow.GetAcrylicAccentState(win); var value = AcrylicHelper.SelectAccentState(state); if (value == AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND) { AcrylicWindow.SetBlur(win, AcrylicAccentState.BlurBehind); InvalidateRect(hwnd, IntPtr.Zero, true); } } else if (msg == WM_EXITSIZEMOVE) { var win = (Window)HwndSource.FromHwnd(hwnd).RootVisual; var state = AcrylicWindow.GetAcrylicAccentState(win); AcrylicWindow.SetBlur(win, state); InvalidateRect(hwnd, IntPtr.Zero, true); if (win != null && _internalStateTable.TryGetValue(win, out var internalState)) { internalState.RestoringState = WindowRestoringState.Default; } } else if (msg == WM_GETMINMAXINFO) { handled = true; var hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); var monitorInfo = new MONITORINFO { cbSize = Marshal.SizeOf(typeof(MONITORINFO)) }; GetMonitorInfo(hMonitor, ref monitorInfo); var info = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); var workingRectangle = monitorInfo.rcWork; var monitorRectangle = monitorInfo.rcMonitor; var win = (Window)HwndSource.FromHwnd(hwnd).RootVisual; GetDpiForMonitor(hMonitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var dpiX, out var dpiY); var maxWidth = win.MaxWidth / 96.0 * dpiX; var maxHeight = win.MaxHeight / 96.0 * dpiY; var minWidth = win.MinWidth / 96.0 * dpiX; var minHeight = win.MinHeight / 96.0 * dpiY; // ウィンドウ最大化時の位置とサイズを指定 info.ptMaxPosition.x = Math.Abs(workingRectangle.left - monitorRectangle.left); info.ptMaxPosition.y = Math.Abs(workingRectangle.top - monitorRectangle.top); info.ptMaxSize.x = (int)Math.Min(Math.Abs(workingRectangle.right - monitorRectangle.left), maxWidth); info.ptMaxSize.y = (int)Math.Min(Math.Abs(workingRectangle.bottom - monitorRectangle.top), maxHeight); // ウィンドウのリサイズ可能サイズを設定 info.ptMaxTrackSize.x = (int)Math.Min(info.ptMaxTrackSize.x, maxWidth); info.ptMaxTrackSize.y = (int)Math.Min(info.ptMaxTrackSize.y, maxHeight); info.ptMinTrackSize.x = (int)Math.Max(info.ptMinTrackSize.x, minWidth); info.ptMinTrackSize.y = (int)Math.Max(info.ptMinTrackSize.y, minHeight); Marshal.StructureToPtr(info, lParam, true); return(IntPtr.Zero); } else if (msg == WM_SIZE && wParam == (IntPtr)SizeEvents.SIZE_MAXIMIZED) { FixMaximizedWindowSize(hwnd); } else if (msg == WM_SIZE && wParam == (IntPtr)SizeEvents.SIZE_RESTORED) { var win = (Window)HwndSource.FromHwnd(hwnd).RootVisual; if (win != null && _internalStateTable.TryGetValue(win, out var internalState)) { win.ClearValue(WindowStyleProperty); if (win.WindowState == WindowState.Maximized && internalState.RestoringState == WindowRestoringState.Default) { internalState.RestoringState = WindowRestoringState.RestoreMove; } if (internalState.RestoringState == WindowRestoringState.Restoring) { internalState.RestoringState = WindowRestoringState.Default; } } } else if (msg == WM_SYSCOMMAND && wParam == (IntPtr)SysCommands.SC_RESTORE) { var win = (Window)HwndSource.FromHwnd(hwnd).RootVisual; if (win != null && _internalStateTable.TryGetValue(win, out var internalState)) { internalState.RestoringState = WindowRestoringState.Restoring; } } else if (msg == WM_WINDOWPOSCHANGING) { var win = (Window)HwndSource.FromHwnd(hwnd).RootVisual; if (win != null && _internalStateTable.TryGetValue(win, out var internalState)) { var pos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS)); if (internalState.RestoringState == WindowRestoringState.RestoreMove && !(pos.x == 0 && pos.y == 0 && pos.cx == 0 && pos.cy == 0)) { GetCursorPos(out var cur); pos.y = cur.y - 8; Marshal.StructureToPtr(pos, lParam, true); } } } return(IntPtr.Zero); }
public static Boolean HandleKeyPress(Boolean isDown, LowLevelListener.KeyHookEventArgs e) { if (!_sEnabled) { return(false); } // If we get here with a letter without our hotkey, exit pronto. if (e.Key != Key.CapsLock && !e.ModifierCapsLock) { return(false); } // Check if the letter has changed whilst the popup is showing, in this case we'll show another selector window. if (_sActiveSelectorWindow != null && _IsLetterPress(e.Key)) { if (_sActiveSelectorWindow.Key != e.Key) { var left = _sActiveSelectorWindow.Left; var top = _sActiveSelectorWindow.Top; _SendSelectedLetterAsKeyPress(); _HidePopup(); if (!LetterMappings.KeyToWindowMap.TryGetValue(e.Key, out _sActiveSelectorWindow)) { return(false); } _ShowPopup(e.ModifierAnyShift, (Int32)left, (Int32)top); return(true); } } if (_sActiveSelectorWindow == null) { if (e.Key == Key.CapsLock) { return(true); // disable capslock } if (!LetterMappings.KeyToWindowMap.TryGetValue(e.Key, out _sActiveSelectorWindow)) { return(false); } } if (_sActiveSelectorWindow == null) { return(false); } var selectorShowing = _sActiveSelectorWindow.IsVisible; // Change case if shift is used. // First we need an additional shift key press to activate it, then we'll handle it as a modifier. if (e.Key == Key.LeftShift || e.Key == Key.RightShift) { if (selectorShowing) { if (isDown) { _sActiveSelectorWindow.ToUpper(); _sShiftTimer.Restart(); } else { _sActiveSelectorWindow.ToLower(); } } return(selectorShowing); } else if (selectorShowing && !e.ModifierAnyShift) { _sActiveSelectorWindow.ToLower(); } // If the selector is showing, and this is a down press, go to next key. if (selectorShowing && isDown && e.Key != Key.CapsLock) { if (e.Key == Key.Left || (e.Key != Key.Right && e.ModifierAnyAlt)) { _sActiveSelectorWindow.SelectPrevious(); } else { _sActiveSelectorWindow.SelectNext(); } return(true); } // If selector is not showing and this is a down press, show it. if (!selectorShowing && isDown && e.Key != Key.CapsLock) { _sActiveKeyboardWindow = GetForegroundWindow(); var position = Caret.GetPosition(_sActiveKeyboardWindow); // Get the monitor on which we are and see if we need to adjust location to avoid falling off. IntPtr monitor; if (position.X == 0 && position.Y == 0) { monitor = MonitorFromWindow(_sActiveKeyboardWindow, MONITOR_DEFAULTTONEAREST); } else { monitor = MonitorFromPoint(position, MONITOR_DEFAULTTONEAREST); } // As far as I understand, WPF's coordinates are relative to the default monitor. // This means that once we've got raw pixels, we need to scale these relative to the DPI of the default // monitor in order to get WPF coordinates. // In the below we'll do everything in raw pixels prior to scaling to WPF coordinates. // The position is measured in dpi of the default monitor. IntPtr defaultMonitor = MonitorFromPoint(default(Point), MONITOR_DEFAULTTOPRIMARY); UInt32 mainDpiX, mainDpiY; Double mainScale = 1.0; if (GetDpiForMonitor(defaultMonitor, DpiType.EFFECTIVE, out mainDpiX, out mainDpiY) == IntPtr.Zero) { // Scale positioning. mainScale = mainDpiX / 96.0; } if (monitor != IntPtr.Zero) { // Get monitor size. MONITORINFO info = new MONITORINFO(); info.cbSize = Marshal.SizeOf(info); if (GetMonitorInfo(monitor, ref info)) { // Convert width and height from WPF coordinates to raw pixels using the scale of the default monitor. var width = _sActiveSelectorWindow.ActualWidth * mainScale; var height = _sActiveSelectorWindow.ActualHeight * mainScale; if (position.X == 0 && position.Y == 0) { // This can happen in two cases: // - there is no caret // - the application does not use win32 caret api // Slap the popup in the middle of the screen as workaround for now. position.X = info.rcWork.Left + (info.rcWork.Right - info.rcWork.Left) / 2 - (Int32)(width / 2.0); position.Y = info.rcWork.Top + (info.rcWork.Bottom - info.rcWork.Top) / 2 - (Int32)(height / 2.0); } // Adjust position to fit within the given dimensions. if (position.X + width > info.rcWork.Right) { position.X = info.rcWork.Right - (Int32)width; } if (position.Y + height > info.rcWork.Bottom) { position.Y = info.rcWork.Bottom - (Int32)height; } } } // If we got nowhere reasonable to put the popup, mark as handled and don't show it. if (position.X == 0 && position.Y == 0) { return(true); } // Finally, convert the position from raw pixels to WPF coordinates. if (mainScale > 1.0) { position.X = (Int32)Math.Round(position.X / mainScale); position.Y = (Int32)Math.Round(position.Y / mainScale); } _ShowPopup(e.ModifierAnyShift, position.X, position.Y); return(true); } // If the selector is showing, mark key as handled. if (selectorShowing && (e.Key != Key.CapsLock || isDown)) { return(true); } // If the selector is not showing, disable the activator key. if (!selectorShowing) { return(true); } // Using the shift key is difficult because the user has to release many keys at once. // Often the shift key is release slightly before the rest which causes the letters to be // lower cased just before selecting. We allow a little time interval in which we ignore the shift up. if (_sShiftTimer.ElapsedMilliseconds < _kReleaseErrorMargin) { _sActiveSelectorWindow.ToUpper(); } // As with the shift key, if the alt key is pressed when the key is sent this really // sends a alt+key shortcut combination to the target application. We allow for an error // margin and delay the sending of input if alt is used (but not enough to be really noticable). // Todo: instead send an alt up? _SendSelectedLetterAsKeyPress(delayInput: e.ModifierAnyAlt); return(true); }
internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
public MonitorInfoWithHandle(IntPtr monitorHandle, MONITORINFO monitorInfo) { MonitorHandle = monitorHandle; MonitorInfo = monitorInfo; }
private void HandleMaximize() { this.borderThicknessChangeNotifier.RaiseValueChanged = false; var raiseValueChanged = this.topMostChangeNotifier.RaiseValueChanged; this.topMostChangeNotifier.RaiseValueChanged = false; var metroWindow = this.AssociatedObject as MetroWindow; var enableDWMDropShadow = this.EnableDWMDropShadow; if (metroWindow != null) { enableDWMDropShadow = metroWindow.GlowBrush == null && (metroWindow.EnableDWMDropShadow || this.EnableDWMDropShadow); } if (this.AssociatedObject.WindowState == WindowState.Maximized) { // remove window border, so we can move the window from top monitor position this.AssociatedObject.BorderThickness = new Thickness(0); var ignoreTaskBar = metroWindow != null && metroWindow.IgnoreTaskbarOnMaximize; if (this.handle != IntPtr.Zero) { this.windowChrome.ResizeBorderThickness = new Thickness(0); // WindowChrome handles the size false if the main monitor is lesser the monitor where the window is maximized // so set the window pos/size twice IntPtr monitor = UnsafeNativeMethods.MonitorFromWindow(this.handle, Constants.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { var monitorInfo = new MONITORINFO(); UnsafeNativeMethods.GetMonitorInfo(monitor, monitorInfo); var x = monitorInfo.rcMonitor.left; var y = monitorInfo.rcMonitor.top; var cx = Math.Abs(monitorInfo.rcMonitor.right - x); var cy = Math.Abs(monitorInfo.rcMonitor.bottom - y); if (ignoreTaskBar && this.isWindwos10OrHigher) { this.ActivateTaskbarFix(); } UnsafeNativeMethods.SetWindowPos(this.handle, new IntPtr(-2), x, y, cx, cy, 0x0040); } } } else { if (!enableDWMDropShadow) { this.AssociatedObject.BorderThickness = this.savedBorderThickness.GetValueOrDefault(new Thickness(0)); } var resizeBorderThickness = this.savedResizeBorderThickness.GetValueOrDefault(new Thickness(0)); if (this.windowChrome.ResizeBorderThickness != resizeBorderThickness) { this.windowChrome.ResizeBorderThickness = resizeBorderThickness; } // #2694 make sure the window is not on top after restoring window // this issue was introduced after fixing the windows 10 bug with the taskbar and a maximized window that ignores the taskbar if (GetHandleTaskbar(this.AssociatedObject) && this.isWindwos10OrHigher) { this.DeactivateTaskbarFix(); } } // fix nasty TopMost bug // - set TopMost="True" // - start mahapps demo // - TopMost works // - maximize window and back to normal // - TopMost is gone // // Problem with minimize animation when window is maximized #1528 // 1. Activate another application (such as Google Chrome). // 2. Run the demo and maximize it. // 3. Minimize the demo by clicking on the taskbar button. // Note that the minimize animation in this case does actually run, but somehow the other // application (Google Chrome in this example) is instantly switched to being the top window, // and so blocking the animation view. this.AssociatedObject.Topmost = false; this.AssociatedObject.Topmost = this.AssociatedObject.WindowState == WindowState.Minimized || this.savedTopMost; this.borderThicknessChangeNotifier.RaiseValueChanged = true; this.topMostChangeNotifier.RaiseValueChanged = raiseValueChanged; }
private void getNativeMonitorResolution(out int width, out int height) { var monitor = MonitorFromWindow(GetActiveWindow(), MONITOR_DEFAULTTONEAREST); MONITORINFO monitorInfo = new MONITORINFO(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); if (!GetMonitorInfo(monitor, ref monitorInfo)) { width = Screen.width; height = Screen.height; } else { width = monitorInfo.rcMonitor.Width; height = monitorInfo.rcMonitor.Height; } }
/// <summary> /// Creates and populates the MINMAXINFO structure for a maximized window. /// Puts the structure into memory address given by lParam. /// Only used to process a WM_GETMINMAXINFO message. /// </summary> /// <param name="hwnd">The window handle.</param> /// <param name="lParam">The lParam.</param> private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { // Get the MINMAXINFO structure from memory location given by lParam MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left); mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top); mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left); mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top); } // Copy the structure to memory location specified by lParam. // This concludes processing of WM_GETMINMAXINFO. Marshal.StructureToPtr(mmi, lParam, true); }
static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam, bool inDragMove) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor IntPtr monitor; if (inDragMove) { POINT pt; GetCursorPos(out pt); // Because the window may not have moved to this monitor yet, use the mouse position // instead of the hwnd to find the monitor (rubber-band drag mode causes this) monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); } else { monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); } if (monitor != System.IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left); mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top); mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left); mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top); } Marshal.StructureToPtr(mmi, lParam, true); }
internal static extern IntPtr MonitorFromPoint(POINT pt, MONITORINFO.MonitorOptions dwFlags);
/// <summary> /// Retrieves information about a display monitor. /// </summary> /// <param name="hMonitor">A handle to the display monitor of interest.</param> /// <param name="info">A MONITORINFO or MONITORINFOEX structure that receives information about the specified display monitor.</param> /// <returns></returns> public static bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO info) { return NativeMethods.GetMonitorInfo(hMonitor, ref info); }
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
public static extern bool GetMonitorInfo(IntPtr hmonitor, [In, Out] MONITORINFO monitorInfo);
private static extern bool GetMonitorInfo(IntPtr monitor, ref MONITORINFO info);
public static extern int GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
public static WriteableBitmap Capture() { try { IntPtr hMonitor = MonitorFromPoint(new POINT(), MonitorOptions.MONITOR_DEFAULTTOPRIMARY); Debug.Assert(hMonitor != IntPtr.Zero); MONITORINFO mi = new MONITORINFO(); mi.cbSize = (uint)Marshal.SizeOf(mi); bool bln = GetMonitorInfo(hMonitor, ref mi); Debug.Assert(bln); int W = mi.rcMonitor.right - mi.rcMonitor.left; int H = mi.rcMonitor.bottom - mi.rcMonitor.top; BITMAPINFOHEADER bmi = new BITMAPINFOHEADER(); bmi.Init(W, H, 32); IntPtr hdcDesktop = GetDC(IntPtr.Zero); Debug.Assert(hdcDesktop != IntPtr.Zero); try { IntPtr hdcMem = CreateCompatibleDC(hdcDesktop); Debug.Assert(hdcMem != IntPtr.Zero); try { IntPtr ppvBits = IntPtr.Zero; IntPtr hbm = CreateDIBSection(hdcMem, ref bmi, 0, out ppvBits, IntPtr.Zero, 0); Debug.Assert(hbm != IntPtr.Zero); try { Debug.Assert(ppvBits != IntPtr.Zero); IntPtr hOldObj = SelectObject(hdcMem, hbm); bln = BitBlt(hdcMem, 0, 0, W, H, hdcDesktop, mi.rcMonitor.left, mi.rcMonitor.top, 0x00CC0020 /* SRCCOPY */); Debug.Assert(bln); GdiFlush(); ReleaseDC(IntPtr.Zero, hdcDesktop); hdcDesktop = IntPtr.Zero; WriteableBitmap wb = new WriteableBitmap(W, H); int[] buf = wb.Pixels; for (int ofs = 0; ofs < H; ++ofs) { Marshal.Copy(new IntPtr(ppvBits.ToInt64() + 4 * W * ofs), buf, (H - 1 - ofs) * W, W); } DeleteDC(hdcMem); hdcMem = IntPtr.Zero; DeleteObject(hbm); hbm = IntPtr.Zero; return wb; } finally { if(hbm != IntPtr.Zero) { DeleteObject(hbm); } } } finally { if(hdcMem != IntPtr.Zero) { DeleteDC(hdcMem); } } } finally { if(hdcDesktop != IntPtr.Zero) { ReleaseDC(IntPtr.Zero, hdcDesktop); } } } catch(Exception e) { for (Exception r = e; r != null; r = r.InnerException) { Debug.WriteLine(r.Message); Debug.WriteLine(r.StackTrace); } return null; } }
private static Rect ToRect(this MONITORINFO @this) => new Rect(@this.work.left, @this.work.top, @this.work.right, @this.work.bottom);
public static Boolean HandleKeyPress(Boolean isDown, LowLevelListener.KeyHookEventArgs e) { if (!_sEnabled) return false; // If we get here with a letter without our hotkey, exit pronto. if (e.Key != Key.CapsLock && !e.ModifierCapsLock) return false; // Check if the letter has changed whilst the popup is showing, in this case we'll show another selector window. if (_sActiveSelectorWindow != null && _IsLetterPress(e.Key)) { if (_sActiveSelectorWindow.Key != e.Key) { var left = _sActiveSelectorWindow.Left; var top = _sActiveSelectorWindow.Top; _HidePopup(); if (!LetterMappings.KeyToWindowMap.TryGetValue(e.Key, out _sActiveSelectorWindow)) return false; _ShowPopup(e.ModifierAnyShift, (Int32)left, (Int32)top); return true; } } if (_sActiveSelectorWindow == null) { if (e.Key == Key.CapsLock) return true; // disable capslock if (!LetterMappings.KeyToWindowMap.TryGetValue(e.Key, out _sActiveSelectorWindow)) return false; } if (_sActiveSelectorWindow == null) return false; var selectorShowing = _sActiveSelectorWindow.IsVisible; // Change case if shift is used. // First we need an additional shift key press to activate it, then we'll handle it as a modifier. if (e.Key == Key.LeftShift || e.Key == Key.RightShift) { if (selectorShowing) { if (isDown) { _sActiveSelectorWindow.ToUpper(); _sShiftTimer.Restart(); } else _sActiveSelectorWindow.ToLower(); } return selectorShowing; } else if (selectorShowing && !e.ModifierAnyShift) { _sActiveSelectorWindow.ToLower(); } // If the selector is showing, and this is a down press, go to next key. if (selectorShowing && isDown && e.Key != Key.CapsLock) { if (e.Key == Key.Left || (e.Key != Key.Right && e.ModifierAnyAlt)) _sActiveSelectorWindow.SelectPrevious(); else _sActiveSelectorWindow.SelectNext(); return true; } // If selector is not showing and this is a down press, show it. if (!selectorShowing && isDown && e.Key != Key.CapsLock) { _sActiveKeyboardWindow = GetForegroundWindow(); var position = Caret.GetPosition(_sActiveKeyboardWindow); // Get the monitor on which we are and see if we need to adjust location to avoid falling off. IntPtr monitor; if (position.X == 0 && position.Y == 0) monitor = MonitorFromWindow(_sActiveKeyboardWindow, MONITOR_DEFAULTTONEAREST); else monitor = MonitorFromPoint(position, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { // Get monitor size. MONITORINFO info = new MONITORINFO(); info.cbSize = Marshal.SizeOf(info); if (GetMonitorInfo(monitor, ref info)) { if (position.X == 0 && position.Y == 0) { // This can happen in two cases: // - there is no caret // - the application does not use win32 caret api // Slap the popup in the middle of the screen as workaround for now. position.X = info.rcWork.Left + (info.rcWork.Right - info.rcWork.Left) / 2 - (Int32)(_sActiveSelectorWindow.ActualWidth / 2.0); position.Y = info.rcWork.Top + (info.rcWork.Bottom - info.rcWork.Top) / 2 - (Int32)(_sActiveSelectorWindow.ActualHeight / 2.0); } // Adjust position to fit within the given dimensions. if (position.X + _sActiveSelectorWindow.ActualWidth > info.rcWork.Right) position.X = info.rcWork.Right - (Int32)_sActiveSelectorWindow.ActualWidth; if (position.Y + _sActiveSelectorWindow.ActualHeight > info.rcWork.Bottom) position.Y = info.rcWork.Bottom - (Int32)_sActiveSelectorWindow.ActualHeight; } } // If we got nowhere reasonable to put the popup, mark as handled and don't show it. if (position.X == 0 && position.Y == 0) return true; _ShowPopup(e.ModifierAnyShift, position.X, position.Y); return true; } // If the selector is showing, mark key as handled. if (selectorShowing && (e.Key != Key.CapsLock || isDown)) return true; // If the selector is not showing, disable the activator key. if (!selectorShowing) return true; // Using the shift key is difficult because the user has to release many keys at once. // Often the shift key is release slightly before the rest which causes the letters to be // lower cased just before selecting. We allow a little time interval in which we ignore the shift up. if (_sShiftTimer.ElapsedMilliseconds < _kReleaseErrorMargin) _sActiveSelectorWindow.ToUpper(); // As with the shift key, if the alt key is pressed when the key is sent this really // sends a alt+key shortcut combination to the target application. We allow for an error // margin and delay the sending of input if alt is used (but not enough to be really noticable). // Todo: instead send an alt up? _SendSelectedLetterAsKeyPress(delayInput: e.ModifierAnyAlt); return true; }
/// <summary> /// Set maximum window size for windows desktop. /// </summary> /// <param name="hwnd"></param> /// <param name="lParam"></param> private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { POINT lMousePosition; GetCursorPos(out lMousePosition); IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY); MONITORINFO lPrimaryScreenInfo = new MONITORINFO(); if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false) { return; } IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST); MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); if (lPrimaryScreen.Equals(lCurrentScreen) == true) { lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left; lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top; lMmi.ptMaxSize.X = Math.Abs(lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left); lMmi.ptMaxSize.Y = Math.Abs(lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top); } else { lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left; lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top; lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left; lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top; } // Adjust for taskbar if autohide is activated. lMmi = AdjustWorkingAreaForAutoHide( MonitorFromWindow(hwnd, MonitorOptions.MONITOR_DEFAULTTONEAREST), lMmi); Marshal.StructureToPtr(lMmi, lParam, true); }
public static bool FitRectOnDesktop(ref Rectangle rect) { bool modified = false; try { Point pt = rect.Location; Size sz = rect.Size; IntPtr hMonitor = MonitorFromPoint(pt, MonitorDefaultTo.Primary); var mi = new MONITORINFO(); mi.cbSize = Marshal.SizeOf(typeof (MONITORINFO)); if (GetMonitorInfo(hMonitor, ref mi)) { Rectangle rcWork = mi.rcWork; if (!rcWork.Contains(pt)) { if (rect.Y < mi.rcWork.Top) rect.Y = mi.rcWork.Top; if (rect.X < mi.rcWork.Left) rect.X = mi.rcWork.Left; if (rect.Y >= mi.rcWork.Bottom) rect.Y = mi.rcWork.Bottom - rect.Height; if (rect.X >= mi.rcWork.Bottom) rect.X = mi.rcWork.Right - rect.Width; pt = rect.Location; sz = rect.Size; modified = true; } } else if (hMonitor == IntPtr.Zero) { pt.X = pt.Y = 0; modified = true; } } catch { } return modified; }
private void MaximizeWithoutCoveringTaskbar() { IntPtr monitor = MonitorFromWindow(_hwnd, MONITOR.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); if (GetMonitorInfo(monitor, monitorInfo)) { RECT rcMonitorArea = monitorInfo.rcMonitor; var x = monitorInfo.rcWork.left; var y = monitorInfo.rcWork.top; var cx = Math.Abs(monitorInfo.rcWork.right - x); var cy = Math.Abs(monitorInfo.rcWork.bottom - y); SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); } } }
private void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor int MONITOR_DEFAULTTONEAREST = 0x00000002; System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != System.IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); mmi.ptMinTrackSize.x = (int)this.MinWidth; mmi.ptMinTrackSize.y = (int)this.MinHeight; } Marshal.StructureToPtr(mmi, lParam, true); }
/// <summary> /// The WmGetMinMaxInfo function creates and populates the MINMAXINFO structure for a maximized window. /// Puts the structure into memory address given by lParam. /// Only used to process a WM_GETMINMAXINFO message. /// </summary> /// <param name="hwnd">The window handle.</param> /// <param name="lParam">The lParam.</param> private void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { // Get the MINMAXINFO structure from memory location given by lParam MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Get the monitor that overlaps the window or the nearest IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { // Get monitor information MONITORINFO monitorInfo = new MONITORINFO(); monitorInfo.Size = Marshal.SizeOf(typeof(MONITORINFO)); GetMonitorInfo(monitor, ref monitorInfo); // The display monitor rectangle. // If the monitor is not the primary display monitor, // some of the rectangle's coordinates may be negative values RECT rcWorkArea = monitorInfo.WorkArea; RECT rcMonitorArea = monitorInfo.Monitor; // Set the dimensions of the window in maximized state mmi.MaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left); mmi.MaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top); mmi.MaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left); mmi.MaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top); // Set the maximum drag X size for the window mmi.MaxTrackSize.X = mmi.MaxSize.X; // Set the maximum drag Y size for the window mmi.MaxTrackSize.Y = mmi.MaxSize.Y; mmi.MinTrackSize.X = (int)MinWidowWidth; mmi.MinTrackSize.Y = (int)MinWidowHeight; // Set the working area depending of TaskBar position and AutoHide status mmi = AdjustWorkingAreaForAutoHide(monitor, mmi); } // Copy the structure to memory location specified by lParam. // This concludes processing of WM_GETMINMAXINFO. Marshal.StructureToPtr(mmi, lParam, true); }
public static extern Boolean GetMonitorInfo( IntPtr hMonitor, MONITORINFO lpmi);
internal static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO monitorInfo);