public static int RegisterBar(AppBarWindow abWindow, double width, double height, ABEdge edge = ABEdge.ABE_TOP) { lock (appBarLock) { APPBARDATA abd = new APPBARDATA(); abd.cbSize = Marshal.SizeOf(typeof(APPBARDATA)); IntPtr handle = new WindowInteropHelper(abWindow).Handle; abd.hWnd = handle; if (!appBars.Contains(handle)) { uCallBack = RegisterWindowMessage("AppBarMessage"); abd.uCallbackMessage = uCallBack; PrepareForInterop(); uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd); InteropDone(); appBars.Add(handle); CairoLogger.Instance.Debug("AppBarHelper: Created AppBar for handle " + handle.ToString()); ABSetPos(abWindow, width, height, edge, true); } else { PrepareForInterop(); SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref abd); InteropDone(); appBars.Remove(handle); CairoLogger.Instance.Debug("AppBarHelper: Removed AppBar for handle " + handle.ToString()); return(0); } } return(uCallBack); }
public static void ABSetPos(AppBarWindow abWindow, double width, double height, ABEdge edge, bool isCreate = false) { lock (appBarLock) { APPBARDATA abd = new APPBARDATA { cbSize = Marshal.SizeOf(typeof(APPBARDATA)), hWnd = abWindow.Handle, uEdge = (int)edge }; int sWidth = (int)width; int sHeight = (int)height; int top = 0; int left = 0; int right = WindowManager.PrimaryMonitorDeviceSize.Width; int bottom = WindowManager.PrimaryMonitorDeviceSize.Height; if (abWindow.Screen != null) { top = abWindow.Screen.Bounds.Y; left = abWindow.Screen.Bounds.X; right = abWindow.Screen.Bounds.Right; bottom = abWindow.Screen.Bounds.Bottom; } if (abd.uEdge == (int)ABEdge.ABE_LEFT || abd.uEdge == (int)ABEdge.ABE_RIGHT) { abd.rc.Top = top; abd.rc.Bottom = bottom; if (abd.uEdge == (int)ABEdge.ABE_LEFT) { abd.rc.Left = left; abd.rc.Right = abd.rc.Left + sWidth; } else { abd.rc.Right = right; abd.rc.Left = abd.rc.Right - sWidth; } } else { abd.rc.Left = left; abd.rc.Right = right; if (abd.uEdge == (int)ABEdge.ABE_TOP) { if (!abWindow.requiresScreenEdge) { abd.rc.Top = top + Convert.ToInt32(GetAppBarEdgeWindowsHeight((ABEdge)abd.uEdge, abWindow.Screen)); } else { abd.rc.Top = top; } abd.rc.Bottom = abd.rc.Top + sHeight; } else { if (!abWindow.requiresScreenEdge) { abd.rc.Bottom = bottom - Convert.ToInt32(GetAppBarEdgeWindowsHeight((ABEdge)abd.uEdge, abWindow.Screen)); } else { abd.rc.Bottom = bottom; } abd.rc.Top = abd.rc.Bottom - sHeight; } } PrepareForInterop(); SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref abd); InteropDone(); // system doesn't adjust all edges for us, do some adjustments switch (abd.uEdge) { case (int)ABEdge.ABE_LEFT: abd.rc.Right = abd.rc.Left + sWidth; break; case (int)ABEdge.ABE_RIGHT: abd.rc.Left = abd.rc.Right - sWidth; break; case (int)ABEdge.ABE_TOP: abd.rc.Bottom = abd.rc.Top + sHeight; break; case (int)ABEdge.ABE_BOTTOM: abd.rc.Top = abd.rc.Bottom - sHeight; break; } PrepareForInterop(); SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref abd); InteropDone(); // check if new coords bool isSameCoords = false; if (!isCreate) { bool topUnchanged = abd.rc.Top == (abWindow.Top * abWindow.dpiScale); bool leftUnchanged = abd.rc.Left == (abWindow.Left * abWindow.dpiScale); bool bottomUnchanged = abd.rc.Bottom == (abWindow.Top * abWindow.dpiScale) + sHeight; bool rightUnchanged = abd.rc.Right == (abWindow.Left * abWindow.dpiScale) + sWidth; isSameCoords = topUnchanged && leftUnchanged && bottomUnchanged && rightUnchanged; } if (!isSameCoords) { CairoLogger.Instance.Debug($"AppBarHelper: {abWindow.Name} changing position (TxLxBxR) to {abd.rc.Top}x{abd.rc.Left}x{abd.rc.Bottom}x{ abd.rc.Right} from {abWindow.Top * abWindow.dpiScale}x{abWindow.Left * abWindow.dpiScale}x{(abWindow.Top * abWindow.dpiScale) + sHeight}x{ (abWindow.Left * abWindow.dpiScale) + sWidth}"); abWindow.SetAppBarPosition(abd.rc); } abWindow.AfterAppBarPos(isSameCoords, abd.rc); if (abd.rc.Bottom - abd.rc.Top < sHeight) { ABSetPos(abWindow, width, height, edge); } } }
public static void ABSetPos(AppBarWindow abWindow, Screen screen, double width, double height, ABEdge edge, bool isCreate = false) { lock (appBarLock) { NativeMethods.APPBARDATA abd = new NativeMethods.APPBARDATA(); abd.cbSize = Marshal.SizeOf(typeof(NativeMethods.APPBARDATA)); IntPtr handle = new WindowInteropHelper(abWindow).Handle; abd.hWnd = handle; abd.uEdge = (int)edge; int sWidth = (int)width; int sHeight = (int)height; int top = 0; int left = 0; int right = WindowManager.PrimaryMonitorDeviceSize.Width; int bottom = WindowManager.PrimaryMonitorDeviceSize.Height; /*PresentationSource ps = PresentationSource.FromVisual(abWindow); * * if (ps == null) * { * // if we are racing with screen setting changes, this will be null * CairoLogger.Instance.Debug("AppBarHelper: Aborting ABSetPos due to window destruction"); * return; * } * * double dpiScale = ps.CompositionTarget.TransformToDevice.M11;*/ if (screen != null) { top = screen.Bounds.Y; left = screen.Bounds.X; right = screen.Bounds.Right; bottom = screen.Bounds.Bottom; } if (abd.uEdge == (int)ABEdge.ABE_LEFT || abd.uEdge == (int)ABEdge.ABE_RIGHT) { abd.rc.top = top; abd.rc.bottom = bottom; if (abd.uEdge == (int)ABEdge.ABE_LEFT) { abd.rc.left = left; abd.rc.right = abd.rc.left + sWidth; } else { abd.rc.right = right; abd.rc.left = abd.rc.right - sWidth; } } else { abd.rc.left = left; abd.rc.right = right; if (abd.uEdge == (int)ABEdge.ABE_TOP) { if (!abWindow.requiresScreenEdge) { abd.rc.top = top + Convert.ToInt32(GetAppBarEdgeWindowsHeight((ABEdge)abd.uEdge, screen)); } else { abd.rc.top = top; } abd.rc.bottom = abd.rc.top + sHeight; } else { if (!abWindow.requiresScreenEdge) { abd.rc.bottom = bottom - Convert.ToInt32(GetAppBarEdgeWindowsHeight((ABEdge)abd.uEdge, screen)); } else { abd.rc.bottom = bottom; } abd.rc.top = abd.rc.bottom - sHeight; } } prepareForInterop(); NativeMethods.SHAppBarMessage((int)NativeMethods.ABMsg.ABM_QUERYPOS, ref abd); interopDone(); // system doesn't adjust all edges for us, do some adjustments switch (abd.uEdge) { case (int)ABEdge.ABE_LEFT: abd.rc.right = abd.rc.left + sWidth; break; case (int)ABEdge.ABE_RIGHT: abd.rc.left = abd.rc.right - sWidth; break; case (int)ABEdge.ABE_TOP: abd.rc.bottom = abd.rc.top + sHeight; break; case (int)ABEdge.ABE_BOTTOM: abd.rc.top = abd.rc.bottom - sHeight; break; } prepareForInterop(); NativeMethods.SHAppBarMessage((int)NativeMethods.ABMsg.ABM_SETPOS, ref abd); interopDone(); // check if new coords bool isSameCoords = false; if (!isCreate) { isSameCoords = abd.rc.top == (abWindow.Top * abWindow.dpiScale) && abd.rc.left == (abWindow.Left * abWindow.dpiScale) && abd.rc.bottom == (abWindow.Top * abWindow.dpiScale) + sHeight && abd.rc.right == (abWindow.Left * abWindow.dpiScale) + sWidth; } if (!isSameCoords) { CairoLogger.Instance.Debug(string.Format("AppBarHelper: {0} changing position (TxLxBxR) to {1}x{2}x{3}x{4} from {5}x{6}x{7}x{8}", abWindow.Name, abd.rc.top, abd.rc.left, abd.rc.bottom, abd.rc.right, (abWindow.Top * abWindow.dpiScale), (abWindow.Left * abWindow.dpiScale), (abWindow.Top * abWindow.dpiScale) + sHeight, (abWindow.Left * abWindow.dpiScale) + sWidth)); abWindow.setAppBarPosition(abd.rc); } abWindow.afterAppBarPos(isSameCoords, abd.rc); if (abd.rc.bottom - abd.rc.top < sHeight) { ABSetPos(abWindow, screen, width, height, edge); } } }