[PATCH 5/8] win32u: Move WM_NCHITTEST implementation from user32.

Jacek Caban wine at gitlab.winehq.org
Wed Jun 15 06:44:36 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
 dlls/user32/defwnd.c |   8 --
 dlls/win32u/defwnd.c | 177 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 177 insertions(+), 8 deletions(-)

diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c
index 6f2c3013aaa..8f32594fd34 100644
--- a/dlls/user32/defwnd.c
+++ b/dlls/user32/defwnd.c
@@ -165,14 +165,6 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
     case WM_NCMOUSELEAVE:
         return NC_HandleNCMouseLeave( hwnd );
 
-    case WM_NCHITTEST:
-        {
-            POINT pt;
-            pt.x = (short)LOWORD(lParam);
-            pt.y = (short)HIWORD(lParam);
-            return NC_HandleNCHitTest( hwnd, pt );
-        }
-
     case WM_WINDOWPOSCHANGED:
         DEFWND_HandleWindowPosChanged( hwnd, (const WINDOWPOS *)lParam );
         break;
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c
index 3705cbf8022..6ec27fc6725 100644
--- a/dlls/win32u/defwnd.c
+++ b/dlls/win32u/defwnd.c
@@ -1621,6 +1621,175 @@ static void handle_nc_calc_size( HWND hwnd, WPARAM wparam, RECT *win_rect )
     }
 }
 
+static LRESULT handle_nc_hit_test( HWND hwnd, POINT pt )
+{
+    RECT rect, client_rect;
+    DWORD style, ex_style;
+
+    TRACE( "hwnd %p pt %d,%d\n", hwnd, pt.x, pt.y );
+
+    get_window_rects( hwnd, COORDS_SCREEN, &rect, &client_rect, get_thread_dpi() );
+    if (!PtInRect( &rect, pt )) return HTNOWHERE;
+
+    style = get_window_long( hwnd, GWL_STYLE );
+    ex_style = get_window_long( hwnd, GWL_EXSTYLE );
+
+    if (PtInRect( &client_rect, pt )) return HTCLIENT;
+
+    /* Check borders */
+    if (has_thick_frame( style, ex_style ))
+    {
+        InflateRect( &rect, -get_system_metrics( SM_CXFRAME ), -get_system_metrics( SM_CYFRAME ));
+        if (!PtInRect( &rect, pt ))
+        {
+            /* Check top sizing border */
+            if (pt.y < rect.top)
+            {
+                if (pt.x < rect.left + get_system_metrics( SM_CXSIZE )) return HTTOPLEFT;
+                if (pt.x >= rect.right - get_system_metrics( SM_CXSIZE )) return HTTOPRIGHT;
+                return HTTOP;
+            }
+            /* Check bottom sizing border */
+            if (pt.y >= rect.bottom)
+            {
+                if (pt.x < rect.left + get_system_metrics( SM_CXSIZE )) return HTBOTTOMLEFT;
+                if (pt.x >= rect.right - get_system_metrics( SM_CXSIZE )) return HTBOTTOMRIGHT;
+                return HTBOTTOM;
+            }
+            /* Check left sizing border */
+            if (pt.x < rect.left)
+            {
+                if (pt.y < rect.top + get_system_metrics( SM_CYSIZE )) return HTTOPLEFT;
+                if (pt.y >= rect.bottom - get_system_metrics( SM_CYSIZE )) return HTBOTTOMLEFT;
+                return HTLEFT;
+            }
+            /* Check right sizing border */
+            if (pt.x >= rect.right)
+            {
+                if (pt.y < rect.top + get_system_metrics( SM_CYSIZE )) return HTTOPRIGHT;
+                if (pt.y >= rect.bottom-get_system_metrics( SM_CYSIZE )) return HTBOTTOMRIGHT;
+                return HTRIGHT;
+            }
+        }
+    }
+    else  /* No thick frame */
+    {
+        if (has_dialog_frame( style, ex_style ))
+            InflateRect( &rect, -get_system_metrics( SM_CXDLGFRAME ),
+                         -get_system_metrics( SM_CYDLGFRAME ));
+        else if (has_thin_frame( style ))
+            InflateRect(&rect, -get_system_metrics( SM_CXBORDER ),
+                        -get_system_metrics( SM_CYBORDER ));
+        if (!PtInRect( &rect, pt )) return HTBORDER;
+    }
+
+    /* Check caption */
+    if ((style & WS_CAPTION) == WS_CAPTION)
+    {
+        if (ex_style & WS_EX_TOOLWINDOW)
+            rect.top += get_system_metrics( SM_CYSMCAPTION ) - 1;
+        else
+            rect.top += get_system_metrics( SM_CYCAPTION ) - 1;
+        if (!PtInRect( &rect, pt ))
+        {
+            BOOL min_or_max_box = (style & WS_SYSMENU) && (style & (WS_MINIMIZEBOX | WS_MAXIMIZEBOX));
+            if (ex_style & WS_EX_LAYOUTRTL)
+            {
+                /* Check system menu */
+                if ((style & WS_SYSMENU) && !(ex_style & WS_EX_TOOLWINDOW) &&
+                    get_nc_icon_for_window( hwnd ))
+                {
+                    rect.right -= get_system_metrics( SM_CYCAPTION ) - 1;
+                    if (pt.x > rect.right) return HTSYSMENU;
+                }
+
+                /* Check close button */
+                if (style & WS_SYSMENU)
+                {
+                    rect.left += get_system_metrics( SM_CYCAPTION );
+                    if (pt.x < rect.left) return HTCLOSE;
+                }
+
+                if (min_or_max_box && !(ex_style & WS_EX_TOOLWINDOW))
+                {
+                    /* Check maximize box */
+                    rect.left += get_system_metrics( SM_CXSIZE );
+                    if (pt.x < rect.left) return HTMAXBUTTON;
+
+                    /* Check minimize box */
+                    rect.left += get_system_metrics( SM_CXSIZE );
+                    if (pt.x < rect.left) return HTMINBUTTON;
+                }
+            }
+            else
+            {
+                /* Check system menu */
+                if ((style & WS_SYSMENU) && !(ex_style & WS_EX_TOOLWINDOW) &&
+                    get_nc_icon_for_window( hwnd ))
+                {
+                    rect.left += get_system_metrics( SM_CYCAPTION ) - 1;
+                    if (pt.x < rect.left) return HTSYSMENU;
+                }
+
+                /* Check close button */
+                if (style & WS_SYSMENU)
+                {
+                    rect.right -= get_system_metrics( SM_CYCAPTION );
+                    if (pt.x > rect.right) return HTCLOSE;
+                }
+
+                if (min_or_max_box && !(ex_style & WS_EX_TOOLWINDOW))
+                {
+                    /* Check maximize box */
+                    rect.right -= get_system_metrics( SM_CXSIZE );
+                    if (pt.x > rect.right) return HTMAXBUTTON;
+
+                    /* Check minimize box */
+                    rect.right -= get_system_metrics( SM_CXSIZE );
+                    if (pt.x > rect.right) return HTMINBUTTON;
+                }
+            }
+            return HTCAPTION;
+        }
+    }
+
+    /* Check menu bar */
+    if (has_menu( hwnd, style ) && (pt.y < client_rect.top) &&
+        (pt.x >= client_rect.left) && (pt.x < client_rect.right))
+        return HTMENU;
+
+    /* Check vertical scroll bar */
+    if (ex_style & WS_EX_LAYOUTRTL) ex_style ^= WS_EX_LEFTSCROLLBAR;
+    if (style & WS_VSCROLL)
+    {
+        if (ex_style & WS_EX_LEFTSCROLLBAR)
+            client_rect.left -= get_system_metrics( SM_CXVSCROLL );
+        else
+            client_rect.right += get_system_metrics( SM_CXVSCROLL );
+        if (PtInRect( &client_rect, pt )) return HTVSCROLL;
+    }
+
+    /* Check horizontal scroll bar */
+    if (style & WS_HSCROLL)
+    {
+        client_rect.bottom += get_system_metrics( SM_CYHSCROLL );
+        if (PtInRect( &client_rect, pt ))
+        {
+            /* Check size box */
+            if ((style & WS_VSCROLL) &&
+                ((ex_style & WS_EX_LEFTSCROLLBAR)
+                 ? (pt.x <= client_rect.left + get_system_metrics( SM_CXVSCROLL ))
+                 : (pt.x >= client_rect.right - get_system_metrics( SM_CXVSCROLL ))))
+                return HTSIZE;
+            return HTHSCROLL;
+        }
+    }
+
+    /* Has to return HTNOWHERE if nothing was found
+       Could happen when a window has a customized non client area */
+    return HTNOWHERE;
+}
+
 LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi )
 {
     LRESULT result = 0;
@@ -1652,6 +1821,14 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
         handle_nc_calc_size( hwnd, wparam, (RECT *)lparam );
         break;
 
+    case WM_NCHITTEST:
+        {
+            POINT pt;
+            pt.x = (short)LOWORD( lparam );
+            pt.y = (short)HIWORD( lparam );
+            return handle_nc_hit_test( hwnd, pt );
+        }
+
     case WM_NCPAINT:
         return handle_nc_paint( hwnd, (HRGN)wparam );
 
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/250



More information about the wine-devel mailing list