コード例 #1
0
        internal static void EnableBlur(Window win)
        {
            // ウィンドウに半透明のアクリル効果を適用する
            var state = AcrylicWindow.GetAcrylicAccentState(win);

            SetBlur(win, state);

            if (!_internalStateTable.TryGetValue(win, out var _))
            {
                var windowHelper = new WindowInteropHelper(win);
                var source       = HwndSource.FromHwnd(windowHelper.Handle);
                source.AddHook(WndProc);

                // タイトルバーの各種ボタンで利用するコマンドの設定
                var closeBinding    = new CommandBinding(SystemCommands.CloseWindowCommand, (_, __) => { SystemCommands.CloseWindow(win); });
                var minimizeBinding = new CommandBinding(SystemCommands.MinimizeWindowCommand, (_, __) => { SystemCommands.MinimizeWindow(win); });
                var maximizeBinding = new CommandBinding(SystemCommands.MaximizeWindowCommand, (_, __) => { SystemCommands.MaximizeWindow(win); });
                var restoreBinding  = new CommandBinding(SystemCommands.RestoreWindowCommand, (_, __) => { SystemCommands.RestoreWindow(win); });
                win.CommandBindings.Add(closeBinding);
                win.CommandBindings.Add(minimizeBinding);
                win.CommandBindings.Add(maximizeBinding);
                win.CommandBindings.Add(restoreBinding);

                var internalState = new AcrylicWindowInternalState()
                {
                    RestoringState  = WindowRestoringState.Default,
                    CloseCommand    = closeBinding,
                    MinimizeCommand = minimizeBinding,
                    MaximizeCommand = maximizeBinding,
                    RestoreCommand  = restoreBinding,
                };
                _internalStateTable.Add(win, internalState);


                // フルスクリーン状態だったら、ウィンドウサイズの訂正をする
                if (win.WindowState == WindowState.Maximized)
                {
                    FixMaximizedWindowSize(windowHelper.Handle);
                }

                // WPFのSizeToContentのバグ対策
                // (WindowChrome使用時に、SizeToContentのウィンドウサイズ計算が正しく行われない)
                void onContentRendered(object sender, EventArgs e)
                {
                    if (win.SizeToContent != SizeToContent.Manual)
                    {
                        win.InvalidateMeasure();
                    }

                    win.ContentRendered -= onContentRendered;
                    InvalidateRect(windowHelper.Handle, IntPtr.Zero, true);
                }

                win.ContentRendered += onContentRendered;
                InvalidateRect(windowHelper.Handle, IntPtr.Zero, true);
            }
        }
コード例 #2
0
        private static void OnAcrylicAccentStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var win = d as Window;

            if (win == null)
            {
                return;
            }

            var isAcrylic = win is AcrylicWindow || AcrylicWindow.GetEnabled(win);

            var newValue = (AcrylicAccentState)e.NewValue;
            var oldValue = (AcrylicAccentState)e.OldValue;

            if (isAcrylic && newValue != oldValue)
            {
                AcrylicWindow.SetBlur(win, newValue);
            }
        }
コード例 #3
0
        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);
        }