[PATCH v2 3/5] win32u: Move WM_NCACTIVATE implementation from user32.

Jacek Caban wine at gitlab.winehq.org
Mon Jun 13 02:03:41 CDT 2022


From: Jacek Caban <jacek at codeweavers.com>

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
 dlls/user32/controls.h  |   1 -
 dlls/user32/defwnd.c    |   3 -
 dlls/user32/nonclient.c | 305 ----------------------------------------
 dlls/win32u/defwnd.c    |  27 ++++
 4 files changed, 27 insertions(+), 309 deletions(-)

diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index b12f56dda6e..83d07e4ad76 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -123,7 +123,6 @@ extern void MENU_EndMenu(HWND) DECLSPEC_HIDDEN;
 extern HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu ) DECLSPEC_HIDDEN;
 
 /* nonclient area */
-extern LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
 extern void NC_HandleNCCalcSize( HWND hwnd, WPARAM wParam, RECT *winRect ) DECLSPEC_HIDDEN;
 extern LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN;
 extern LRESULT NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c
index 89bf2c78ce4..9b23d1e6315 100644
--- a/dlls/user32/defwnd.c
+++ b/dlls/user32/defwnd.c
@@ -253,9 +253,6 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
                         (short)LOWORD(lParam), (short)HIWORD(lParam), 0, hwnd, NULL );
         return 0;
 
-    case WM_NCACTIVATE:
-        return NC_HandleNCActivate( hwnd, wParam, lParam );
-
     case WM_PRINT:
         DEFWND_Print(hwnd, (HDC)wParam, lParam);
         return 0;
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c
index b8703df8fd1..dab6b73ee1c 100644
--- a/dlls/user32/nonclient.c
+++ b/dlls/user32/nonclient.c
@@ -799,311 +799,6 @@ static void  NC_DrawMinButton(HWND hwnd,HDC hdc,BOOL down, BOOL bGrayed)
     DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
 }
 
-/******************************************************************************
- *
- *   NC_DrawFrame
- *
- *   Draw a window frame inside the given rectangle, and update the rectangle.
- *
- *   Bugs
- *        Many.  First, just what IS a frame in Win95?  Note that the 3D look
- *        on the outer edge is handled by NC_DoNCPaint.  As is the inner
- *        edge.  The inner rectangle just inside the frame is handled by the
- *        Caption code.
- *
- *        In short, for most people, this function should be a nop (unless
- *        you LIKE thick borders in Win95/NT4.0 -- I've been working with
- *        them lately, but just to get this code right).  Even so, it doesn't
- *        appear to be so.  It's being worked on...
- *
- *****************************************************************************/
-
-static void  NC_DrawFrame( HDC  hdc, RECT  *rect, BOOL  active, DWORD style, DWORD exStyle)
-{
-    INT width, height;
-
-    /* Firstly the "thick" frame */
-    if (style & WS_THICKFRAME)
-    {
-        width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME);
-        height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME);
-
-        SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
-                                            COLOR_INACTIVEBORDER) );
-        /* Draw frame */
-        PatBlt( hdc, rect->left, rect->top,
-                  rect->right - rect->left, height, PATCOPY );
-        PatBlt( hdc, rect->left, rect->top,
-                  width, rect->bottom - rect->top, PATCOPY );
-        PatBlt( hdc, rect->left, rect->bottom - 1,
-                  rect->right - rect->left, -height, PATCOPY );
-        PatBlt( hdc, rect->right - 1, rect->top,
-                  -width, rect->bottom - rect->top, PATCOPY );
-
-        InflateRect( rect, -width, -height );
-    }
-
-    /* Now the other bit of the frame */
-    if ((style & (WS_BORDER|WS_DLGFRAME)) ||
-        (exStyle & WS_EX_DLGMODALFRAME))
-    {
-        width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
-        height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
-        /* This should give a value of 1 that should also work for a border */
-
-        SelectObject( hdc, GetSysColorBrush(
-                      (exStyle & (WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE)) ?
-                          COLOR_3DFACE :
-                      (exStyle & WS_EX_STATICEDGE) ?
-                          COLOR_WINDOWFRAME :
-                      (style & (WS_DLGFRAME|WS_THICKFRAME)) ?
-                          COLOR_3DFACE :
-                      /* else */
-                          COLOR_WINDOWFRAME));
-
-        /* Draw frame */
-        PatBlt( hdc, rect->left, rect->top,
-                  rect->right - rect->left, height, PATCOPY );
-        PatBlt( hdc, rect->left, rect->top,
-                  width, rect->bottom - rect->top, PATCOPY );
-        PatBlt( hdc, rect->left, rect->bottom - 1,
-                  rect->right - rect->left, -height, PATCOPY );
-        PatBlt( hdc, rect->right - 1, rect->top,
-                  -width, rect->bottom - rect->top, PATCOPY );
-
-        InflateRect( rect, -width, -height );
-    }
-}
-
-
-/******************************************************************************
- *
- *   NC_DrawCaption
- *
- *   Draw the window caption for windows.
- *   The correct pen for the window frame must be selected in the DC.
- *
- *****************************************************************************/
-
-static void  NC_DrawCaption( HDC  hdc, RECT *rect, HWND hwnd, DWORD  style, 
-                             DWORD  exStyle, BOOL active )
-{
-    RECT  r = *rect;
-    WCHAR buffer[256];
-    HPEN  hPrevPen;
-    HMENU hSysMenu;
-    BOOL gradient = FALSE;
-
-    hPrevPen = SelectObject( hdc, SYSCOLOR_GetPen(
-                     ((exStyle & (WS_EX_STATICEDGE|WS_EX_CLIENTEDGE|
-                                 WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
-                      COLOR_WINDOWFRAME : COLOR_3DFACE) );
-    MoveToEx( hdc, r.left, r.bottom - 1, NULL );
-    LineTo( hdc, r.right, r.bottom - 1 );
-    SelectObject( hdc, hPrevPen );
-    r.bottom--;
-
-    SystemParametersInfoW (SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0);
-    NC_DrawCaptionBar (hdc, &r, style, active, gradient);
-
-    if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
-        if (NC_DrawSysButton (hwnd, hdc, FALSE))
-            r.left += GetSystemMetrics(SM_CXSMICON) + 2;
-    }
-
-    if (style & WS_SYSMENU)
-    {
-        UINT state;
-
-        /* Go get the sysmenu */
-        hSysMenu = NtUserGetSystemMenu(hwnd, FALSE);
-        state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
-
-        /* Draw a grayed close button if disabled or if SC_CLOSE is not there */
-        NC_DrawCloseButton (hwnd, hdc, FALSE,
-                            (state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF));
-        r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
-
-        if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
-        {
-            /* In win95 the two buttons are always there */
-            /* But if the menu item is not in the menu they're disabled*/
-
-            NC_DrawMaxButton( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
-            r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-
-            NC_DrawMinButton( hwnd, hdc, FALSE,  (!(style & WS_MINIMIZEBOX)));
-            r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
-        }
-    }
-
-    if (GetWindowTextW( hwnd, buffer, ARRAY_SIZE( buffer )))
-    {
-        NONCLIENTMETRICSW nclm;
-        HFONT hFont, hOldFont;
-        nclm.cbSize = sizeof(nclm);
-        SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
-        if (exStyle & WS_EX_TOOLWINDOW)
-            hFont = CreateFontIndirectW (&nclm.lfSmCaptionFont);
-        else
-            hFont = CreateFontIndirectW (&nclm.lfCaptionFont);
-        hOldFont = SelectObject (hdc, hFont);
-        if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
-        else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
-        SetBkMode( hdc, TRANSPARENT );
-        r.left += 2;
-        DrawTextW( hdc, buffer, -1, &r,
-                     DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
-        DeleteObject (SelectObject (hdc, hOldFont));
-    }
-}
-
-
-/******************************************************************************
- *   NC_DoNCPaint
- *
- *   Paint the non-client area for windows.
- */
-static void  NC_DoNCPaint( HWND  hwnd, HRGN  clip )
-{
-    HDC hdc;
-    RECT rfuzz, rect, rectClip;
-    BOOL active;
-    WND *wndPtr;
-    DWORD dwStyle, dwExStyle;
-    WORD flags;
-    HRGN hrgn;
-    RECT rectClient;
-
-    if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
-    dwStyle = wndPtr->dwStyle;
-    dwExStyle = wndPtr->dwExStyle;
-    flags = wndPtr->flags;
-    WIN_ReleasePtr( wndPtr );
-
-    active  = flags & WIN_NCACTIVATED;
-
-    TRACE("%p %d\n", hwnd, active );
-
-    /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
-       the call to GetDCEx implying that it is allowed not to use it either.
-       However, the suggested GetDCEx(    , DCX_WINDOW | DCX_INTERSECTRGN)
-       will cause clipRgn to be deleted after ReleaseDC().
-       Now, how is the "system" supposed to tell what happened?
-     */
-
-    WIN_GetRectangles( hwnd, COORDS_SCREEN, NULL, &rectClient );
-    hrgn = CreateRectRgnIndirect( &rectClient );
-
-    if (clip > (HRGN)1)
-    {
-        CombineRgn( hrgn, clip, hrgn, RGN_DIFF );
-        hdc = NtUserGetDCEx( hwnd, hrgn, DCX_USESTYLE | DCX_WINDOW | DCX_INTERSECTRGN );
-    }
-    else
-    {
-        hdc = NtUserGetDCEx( hwnd, hrgn, DCX_USESTYLE | DCX_WINDOW | DCX_EXCLUDERGN );
-    }
-
-    if (!hdc)
-    {
-        DeleteObject( hrgn );
-        return;
-    }
-
-    WIN_GetRectangles( hwnd, COORDS_WINDOW, &rect, NULL );
-    GetClipBox( hdc, &rectClip );
-
-    SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
-
-    if (HAS_STATICOUTERFRAME(dwStyle, dwExStyle)) {
-        DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
-    }
-    else if (HAS_BIGFRAME( dwStyle, dwExStyle)) {
-        DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
-    }
-
-    NC_DrawFrame(hdc, &rect, active, dwStyle, dwExStyle );
-
-    if ((dwStyle & WS_CAPTION) == WS_CAPTION)
-    {
-        RECT  r = rect;
-        if (dwExStyle & WS_EX_TOOLWINDOW) {
-            r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
-            rect.top += GetSystemMetrics(SM_CYSMCAPTION);
-        }
-        else {
-            r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
-            rect.top += GetSystemMetrics(SM_CYCAPTION);
-        }
-        if( IntersectRect( &rfuzz, &r, &rectClip ) )
-            NC_DrawCaption(hdc, &r, hwnd, dwStyle, dwExStyle, active);
-    }
-
-    if (HAS_MENU( hwnd, dwStyle ))
-    {
-	RECT r = rect;
-	r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
-
-	TRACE("Calling DrawMenuBar with rect (%s)\n", wine_dbgstr_rect(&r));
-
-	rect.top += MENU_DrawMenuBar( hdc, &r, hwnd ) + 1;
-    }
-
-    TRACE("After MenuBar, rect is (%s).\n", wine_dbgstr_rect(&rect));
-
-    if (dwExStyle & WS_EX_CLIENTEDGE)
-	DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
-
-    /* Draw the scroll-bars */
-    SCROLL_DrawNCScrollBar( hwnd, hdc, dwStyle & WS_HSCROLL, dwStyle & WS_VSCROLL );
-
-    /* Draw the "size-box" */
-    if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
-    {
-        RECT r = rect;
-        if((dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
-            r.right = r.left + GetSystemMetrics(SM_CXVSCROLL) + 1;
-        else
-            r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
-        r.top  = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
-        FillRect( hdc, &r, GetSysColorBrush( COLOR_BTNFACE ) );
-    }
-
-    NtUserReleaseDC( hwnd, hdc );
-}
-
-
-/***********************************************************************
- *           NC_HandleNCActivate
- *
- * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
- */
-LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam )
-{
-    /* Lotus Notes draws menu descriptions in the caption of its main
-     * window. When it wants to restore original "system" view, it just
-     * sends WM_NCACTIVATE message to itself. Any optimizations here in
-     * attempt to minimize redrawings lead to a not restored caption.
-     */
-    if (wParam) win_set_flags( hwnd, WIN_NCACTIVATED, 0 );
-    else win_set_flags( hwnd, 0, WIN_NCACTIVATED );
-
-    /* This isn't documented but is reproducible in at least XP SP2 and
-     * Outlook 2007 depends on it
-     */
-    if (lParam != -1)
-    {
-        NC_DoNCPaint( hwnd, (HRGN)1 );
-
-        if (NtUserGetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
-            PostMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
-    }
-
-    return TRUE;
-}
-
-
 /***********************************************************************
  *           NC_HandleSetCursor
  *
diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c
index 8d94bbaad90..db8187a3ea1 100644
--- a/dlls/win32u/defwnd.c
+++ b/dlls/win32u/defwnd.c
@@ -1463,6 +1463,30 @@ static LRESULT handle_nc_paint( HWND hwnd , HRGN clip )
     return 0;
 }
 
+static LRESULT handle_nc_activate( HWND hwnd, WPARAM wparam, LPARAM lparam )
+{
+    /* Lotus Notes draws menu descriptions in the caption of its main
+     * window. When it wants to restore original "system" view, it just
+     * sends WM_NCACTIVATE message to itself. Any optimizations here in
+     * attempt to minimize redrawings lead to a not restored caption.
+     */
+    if (wparam) win_set_flags( hwnd, WIN_NCACTIVATED, 0 );
+    else win_set_flags( hwnd, 0, WIN_NCACTIVATED );
+
+    /* This isn't documented but is reproducible in at least XP SP2 and
+     * Outlook 2007 depends on it
+     */
+    if (lparam != -1)
+    {
+        nc_paint( hwnd, (HRGN)1 );
+
+        if (NtUserGetAncestor( hwnd, GA_PARENT ) == get_desktop_window())
+            NtUserPostMessage( get_desktop_window(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
+    }
+
+    return TRUE;
+}
+
 LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi )
 {
     LRESULT result = 0;
@@ -1493,6 +1517,9 @@ LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
     case WM_NCPAINT:
         return handle_nc_paint( hwnd, (HRGN)wparam );
 
+    case WM_NCACTIVATE:
+        return handle_nc_activate( hwnd, wparam, lparam );
+
     case WM_WINDOWPOSCHANGING:
         return handle_window_pos_changing( hwnd, (WINDOWPOS *)lparam );
 
-- 
GitLab


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



More information about the wine-devel mailing list