private IntPtr DragHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
 {
     switch ((Utils.WM)msg)
     {
     case Utils.WM.WM_DPICHANGED:
         Utils.RECT rect = (Utils.RECT)Marshal.PtrToStructure(lParam, typeof(Utils.RECT));
         if (rect.left != -32000 && rect.top != -32000)
         {
             Utils.MySetWindowPos(hwnd, new System.Windows.Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top));
         }
         break;
     }
     return(IntPtr.Zero);
 }
 private IntPtr DragHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
 {
     switch ((Utils.WM)msg)
     {
     case Utils.WM.WM_DPICHANGED:
         Utils.RECT rect = (Utils.RECT)Marshal.PtrToStructure(lParam, typeof(Utils.RECT));
         if (CallController.Instance.CurrentCallStatus != CallStatus.Connected)
         {
             Utils.MySetWindowPos(hwnd, new System.Windows.Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top));
         }
         break;
     }
     return(IntPtr.Zero);
 }
        private IntPtr DragHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            //if(this.WindowState == WindowState.Maximized)
            //{
            //    return IntPtr.Zero;
            //}

            //if (0x0200 == msg || 0x0084 == msg || 0x0020 == msg || 0x00A0 == msg)
            //{
            //    return IntPtr.Zero;
            //}

            //log.DebugFormat("Main Window DragHook, msg={0:X000}, hwnd={1:X000}", msg, hwnd);

            //if (0x0005 == msg)
            //{
            //    int width = LOWORD((uint)lParam);
            //    int height = HIWORD((uint)lParam);
            //    log.DebugFormat("Main window receive msg WM_SIZE, width={0}, height={1}", width, height);
            //}

            switch ((Utils.WM)msg)
            {
            case Utils.WM.WM_GETMINMAXINFO:
            {
                //    log.DebugFormat("WM.WM_GETMINMAXINFO, window state:{0}", this.WindowState);
                WmGetMinMaxInfo(hwnd, lParam);
                handled = true;
            }
            break;

            case Utils.WM.WM_SYSCOMMAND:
            {
                //    log.DebugFormat("receive syscommand: {0:X000}, window state:{1}", (int)wParam, this.WindowState);
                if (wParam == new IntPtr(0xF030))         // Maximize event - SC_MAXIMIZE from Winuser.h
                {
                    //    log.Debug("WM.WM_SYSCOMMAND -- wParam == new IntPtr(0xF030)");
                    _maximized = true;
                }
                else if (wParam == new IntPtr(0xF120) || wParam == new IntPtr(0xF020))         // SC_RESTORE or SC_MINIMIZE
                {
                    //    log.Debug("WM.WM_SYSCOMMAND -- wParam == new IntPtr(0xF120) || wParam == new IntPtr(0xF020)");
                    // do nothing
                }
                else
                {
                    //    log.DebugFormat("WM.WM_SYSCOMMAND -- else, wParam={0:X000}", wParam);
                    _maximized = false;
                }
            }
            break;

            case Utils.WM.WINDOWPOSCHANGING:
            {
                if (FullScreenStatus)
                {
                    return(IntPtr.Zero);
                }
                Utils.WINDOWPOS pos = (Utils.WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(Utils.WINDOWPOS));
                //log.DebugFormat("WM.WINDOWPOSCHANGING, window state:{0}", this.WindowState);
                if (_maximized)
                {
                    //log.DebugFormat("WM.WINDOWPOSCHANGING -- _maximized, position:x={0}, y={1}, cx={2}, cy={3}, width={4}, height={5}", pos.x, pos.y, pos.cx, pos.cy, this.Width, this.Height);
                    if (pos.x > -32000 && pos.y > -32000 && 0 != pos.cx && 0 != pos.cy)
                    {
                        if ((pos.cx != _maxWindowWidth || pos.cy != _maxWindowHeight) && (_maxWindowWidth > 0 && _maxWindowHeight > 0))
                        {
                            //The size of window is not equal to the maximize and set to the maximize.
                            log.DebugFormat("The size of window is not equal to the maximize and set to the maximize. pos.cx={0}, pos.cy={1}, maxCx={2}, maxCy={3}", pos.cx, pos.cy, _maxWindowWidth, _maxWindowHeight);
                            pos.cx = _maxWindowWidth;
                            pos.cy = _maxWindowHeight;
                            Marshal.StructureToPtr(pos, lParam, true);
                            handled = true;
                        }
                    }

                    return(IntPtr.Zero);
                }

                if (_maxWinWhenLoaded)
                {
                    _maxWinWhenLoaded = false;
                    FullScreenStatus  = false;
                    ChangeWindowState(WindowState.Maximized);
                    return(IntPtr.Zero);
                }

                if ((pos.flags & (int)Utils.SWP_NOMOVE) != 0)
                {
                    //log.Debug("WM.WINDOWPOSCHANGING -- (pos.flags & (int)SWP.NOMOVE) != 0");
                    return(IntPtr.Zero);
                }

                Window wnd = (Window)HwndSource.FromHwnd(hwnd).RootVisual;
                if (wnd == null)
                {
                    //log.Debug("WM.WINDOWPOSCHANGING -- wnd == null");
                    return(IntPtr.Zero);
                }

                if ((pos.cx == _maxWindowWidth && pos.cy == _maxWindowHeight) && (_maxWindowWidth > 0 && _maxWindowHeight > 0))
                {
                    log.DebugFormat("The window maybe is maximized.");
                    return(IntPtr.Zero);
                }

                if ((pos.cx > _maxWindowWidth || pos.cy > _maxWindowHeight) && (_maxWindowWidth > 0 && _maxWindowHeight > 0))
                {
                    // The window size exceed the max size. Maybe the window is maximized by dragging the window to the top
                    log.Debug("The window size exceed the max size. Maybe the window is maximized by dragging the window to the top");
                    pos.cx = _maxWindowWidth;
                    pos.cy = _maxWindowHeight;
                    Marshal.StructureToPtr(pos, lParam, true);
                    handled = true;
                    return(IntPtr.Zero);
                }

                if ((pos.cx == _maxWindowWidth || pos.cy == _maxWindowHeight) && (_maxWindowWidth > 0 && _maxWindowHeight > 0))
                {
                    log.Debug("The window maybe is dragged to the right of left of screen to half max.");
                    handled = true;
                    return(IntPtr.Zero);
                }

                //log.DebugFormat("Main window original position, x={0}, y={1}, cx={2}, cy={3}", pos.x, pos.y, pos.cx, pos.cy);


                // determine what dimension is changed by detecting the mouse position relative to the
                // window bounds. if gripped in the corner, either will work.
                if (!_adjustingHeight.HasValue)
                {
                    Point p = Utils.GetMousePosition();

                    double diffWidth  = Math.Min(Math.Abs(p.X - pos.x), Math.Abs(p.X - pos.x - pos.cx));
                    double diffHeight = Math.Min(Math.Abs(p.Y - pos.y), Math.Abs(p.Y - pos.y - pos.cy));

                    _adjustingHeight = diffHeight > diffWidth;
                }

                if (_adjustingHeight.Value)
                {
                    //    log.DebugFormat("Adjust pos.cy, original pos.cy:{0}", pos.cy);
                    pos.cy = (int)((pos.cx / _aspectRatio) + _titlebarHeight * (DpiY / 96d));         // adjusting height to width change
                    //    log.DebugFormat("Changed pos.cy:{0}", pos.cy);
                }
                else
                {
                    //    log.DebugFormat("Adjust pos.cx, original pos.cx:{0}", pos.cx);
                    pos.cx = (int)((pos.cy - _titlebarHeight * (DpiY / 96d)) * _aspectRatio);         // adjusting width to heigth change
                    //    log.DebugFormat("Changed pos.cx:{0}", pos.cx);
                }
                //log.InfoFormat("Main window changed position, x={0}, y={1}, cx={2}, cy={3}", pos.x, pos.y, pos.cx, pos.cy);
                Marshal.StructureToPtr(pos, lParam, true);
                handled = true;
            }
            break;

            case Utils.WM.EXITSIZEMOVE:
                //log.Debug("WM.EXITSIZEMOVE");
                _adjustingHeight = null;     // reset adjustment dimension and detect again next time window is resized
                break;

            case Utils.WM.WM_DPICHANGED:
                Utils.RECT rect = (Utils.RECT)Marshal.PtrToStructure(lParam, typeof(Utils.RECT));
                if (rect.left != -32000 && rect.top != -32000)
                {
                    //sync trigger system event(DisplaySettingChanged and DpiChanged)
                    //if first trigger DisplaySettingChanged, after trigger DpiChanged, skip DpiChanged event;because DpiChanged position is wrong;
                    if ((DateTime.Now - _displaySettingChangedTime).TotalSeconds >= 2)
                    {
                        UpdateDpiValue();
                        Utils.MySetWindowPos(hwnd, new Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top));
                        DpiChanged?.Invoke();
                    }
                }
                else
                {
                    log.DebugFormat("--------------neglect dpichanged, because rect.left={0}, rect.top={1}", rect.left, rect.top);
                }
                break;
            }

            return(IntPtr.Zero);
        }