Commit c196d246 authored by Zhiyi Zhang's avatar Zhiyi Zhang Committed by Alexandre Julliard

user32: Hook drawing menu buttons.

parent 077c4626
......@@ -72,6 +72,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
static struct user_api_hook original_user_api =
{
USER_DefDlgProc,
USER_NonClientButtonDraw,
USER_ScrollBarDraw,
USER_ScrollBarProc,
};
......
......@@ -172,3 +172,51 @@ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam )
}
return 0;
}
static void user_draw_mdi_button( HDC hdc, enum NONCLIENT_BUTTON_TYPE type, RECT rect, BOOL down, BOOL grayed )
{
UINT flags;
switch (type)
{
case MENU_CLOSE_BUTTON:
flags = DFCS_CAPTIONCLOSE;
break;
case MENU_MIN_BUTTON:
flags = DFCS_CAPTIONMIN;
break;
case MENU_MAX_BUTTON:
flags = DFCS_CAPTIONMAX;
break;
case MENU_RESTORE_BUTTON:
flags = DFCS_CAPTIONRESTORE;
break;
case MENU_HELP_BUTTON:
flags = DFCS_CAPTIONHELP;
break;
default:
return;
}
if (down)
flags |= DFCS_PUSHED;
if (grayed)
flags |= DFCS_INACTIVE;
DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
}
void WINAPI USER_NonClientButtonDraw( HWND hwnd, HDC hdc, enum NONCLIENT_BUTTON_TYPE type,
RECT rect, BOOL down, BOOL grayed )
{
switch (type)
{
case MENU_CLOSE_BUTTON:
case MENU_MIN_BUTTON:
case MENU_MAX_BUTTON:
case MENU_RESTORE_BUTTON:
case MENU_HELP_BUTTON:
user_draw_mdi_button( hdc, type, rect, down, grayed );
return;
}
}
......@@ -104,6 +104,13 @@ static NTSTATUS WINAPI User32CopyImage( const struct copy_image_params *params,
return HandleToUlong( ret );
}
static NTSTATUS WINAPI User32DrawNonClientButton( const struct draw_non_client_button_params *params, ULONG size )
{
user_api->pNonClientButtonDraw( params->hwnd, params->hdc, params->type, params->rect,
params->down, params->grayed );
return 0;
}
static NTSTATUS WINAPI User32DrawScrollBar( const struct draw_scroll_bar_params *params, ULONG size )
{
RECT rect = params->rect;
......@@ -200,6 +207,7 @@ static const void *kernel_callback_table[NtUserCallCount] =
User32CallWindowProc,
User32CallWindowsHook,
User32CopyImage,
User32DrawNonClientButton,
User32DrawScrollBar,
User32DrawText,
User32FreeCachedClipboardData,
......
......@@ -158,6 +158,7 @@ extern BOOL get_icon_size( HICON handle, SIZE *size ) DECLSPEC_HIDDEN;
extern struct user_api_hook *user_api DECLSPEC_HIDDEN;
LRESULT WINAPI USER_DefDlgProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
void WINAPI USER_NonClientButtonDraw(HWND, HDC, enum NONCLIENT_BUTTON_TYPE, RECT, BOOL, BOOL) DECLSPEC_HIDDEN;
void WINAPI USER_ScrollBarDraw(HWND, HDC, INT, enum SCROLL_HITTEST,
const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT,
INT, INT, INT, BOOL) DECLSPEC_HIDDEN;
......
......@@ -14,6 +14,7 @@ C_SRCS = \
scrollbar.c \
stylemap.c \
system.c \
uxini.c
uxini.c \
window.c
RC_SRCS = version.rc
......@@ -1245,6 +1245,7 @@ BOOL WINAPI ThemeHooksInstall(void)
struct user_api_hook hooks;
hooks.pDefDlgProc = UXTHEME_DefDlgProc;
hooks.pNonClientButtonDraw = UXTHEME_NonClientButtonDraw;
hooks.pScrollBarDraw = UXTHEME_ScrollBarDraw;
hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc;
return RegisterUserApiHook(&hooks, &user_api);
......
......@@ -107,6 +107,8 @@ extern void UXTHEME_UninitSystem(void) DECLSPEC_HIDDEN;
extern struct user_api_hook user_api DECLSPEC_HIDDEN;
LRESULT WINAPI UXTHEME_DefDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL unicode) DECLSPEC_HIDDEN;
void WINAPI UXTHEME_NonClientButtonDraw(HWND hwnd, HDC hdc, enum NONCLIENT_BUTTON_TYPE type,
RECT rect, BOOL down, BOOL grayed) DECLSPEC_HIDDEN;
void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTEST hit_test,
const struct SCROLL_TRACKING_INFO *tracking_info,
BOOL draw_arrows, BOOL draw_interior, RECT *rect, UINT enable_flags,
......
/*
* Window theming support
*
* Copyright 2022 Zhiyi Zhang for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "uxthemedll.h"
void WINAPI UXTHEME_NonClientButtonDraw(HWND hwnd, HDC hdc, enum NONCLIENT_BUTTON_TYPE type,
RECT rect, BOOL down, BOOL grayed)
{
user_api.pNonClientButtonDraw(hwnd, hdc, type, rect, down, grayed);
}
......@@ -1351,6 +1351,22 @@ BOOL draw_frame_caption( HDC dc, RECT *r, UINT flags )
return TRUE;
}
BOOL draw_menu_button( HWND hwnd, HDC dc, RECT *r, enum NONCLIENT_BUTTON_TYPE type, BOOL down,
BOOL grayed )
{
struct draw_non_client_button_params params;
void *ret_ptr;
ULONG ret_len;
params.hwnd = hwnd;
params.hdc = dc;
params.type = type;
params.rect = *r;
params.down = down;
params.grayed = grayed;
return KeUserModeCallback( NtUserDrawNonClientButton, &params, sizeof(params), &ret_ptr, &ret_len );
}
BOOL draw_frame_menu( HDC dc, RECT *r, UINT flags )
{
RECT rect;
......
......@@ -2221,7 +2221,7 @@ static void draw_popup_arrow( HDC hdc, RECT rect, UINT arrow_width, UINT arrow_h
NtGdiDeleteObjectApp( mem_hdc );
}
static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect,
static void draw_bitmap_item( HWND hwnd, HDC hdc, struct menu_item *item, const RECT *rect,
struct menu *menu, HWND owner, UINT odaction )
{
int w = rect->right - rect->left;
......@@ -2236,7 +2236,8 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect,
/* Check if there is a magic menu item associated with this item */
if (IS_MAGIC_BITMAP( bmp_to_draw ))
{
UINT flags = 0;
BOOL down = FALSE, grayed = FALSE;
enum NONCLIENT_BUTTON_TYPE type;
WCHAR bmchr = 0;
RECT r;
......@@ -2262,19 +2263,21 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect,
}
goto got_bitmap;
case (INT_PTR)HBMMENU_MBAR_RESTORE:
flags = DFCS_CAPTIONRESTORE;
type = MENU_RESTORE_BUTTON;
break;
case (INT_PTR)HBMMENU_MBAR_MINIMIZE:
flags = DFCS_CAPTIONMIN;
type = MENU_MIN_BUTTON;
break;
case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D:
flags = DFCS_CAPTIONMIN | DFCS_INACTIVE;
type = MENU_MIN_BUTTON;
grayed = TRUE;
break;
case (INT_PTR)HBMMENU_MBAR_CLOSE:
flags = DFCS_CAPTIONCLOSE;
type = MENU_CLOSE_BUTTON;
break;
case (INT_PTR)HBMMENU_MBAR_CLOSE_D:
flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
type = MENU_CLOSE_BUTTON;
grayed = TRUE;
break;
case (INT_PTR)HBMMENU_CALLBACK:
{
......@@ -2333,8 +2336,8 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect,
{
r = *rect;
InflateRect( &r, -1, -1 );
if (item->fState & MF_HILITE) flags |= DFCS_PUSHED;
draw_frame_caption( hdc, &r, flags );
if (item->fState & MF_HILITE) down = TRUE;
draw_menu_button( hwnd, hdc, &r, type, down, grayed );
}
return;
}
......@@ -2605,7 +2608,7 @@ static void draw_menu_item( HWND hwnd, struct menu *menu, HWND owner, HDC hdc,
POINT origorg;
/* some applications make this assumption on the DC's origin */
set_viewport_org( hdc, rect.left, rect.top, &origorg );
draw_bitmap_item( hdc, item, &bmprc, menu, owner, odaction );
draw_bitmap_item( hwnd, hdc, item, &bmprc, menu, owner, odaction );
set_viewport_org( hdc, origorg.x, origorg.y, NULL );
}
/* Draw the popup-menu arrow */
......@@ -2621,7 +2624,7 @@ static void draw_menu_item( HWND hwnd, struct menu *menu, HWND owner, HDC hdc,
POINT origorg;
set_viewport_org( hdc, rect.left, rect.top, &origorg);
draw_bitmap_item( hdc, item, &bmprc, menu, owner, odaction );
draw_bitmap_item( hwnd, hdc, item, &bmprc, menu, owner, odaction );
set_viewport_org( hdc, origorg.x, origorg.y, NULL);
}
/* process text if present */
......
......@@ -241,7 +241,7 @@ extern void register_window_surface( struct window_surface *old,
extern LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
BOOL ansi ) DECLSPEC_HIDDEN;
extern LRESULT desktop_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;
extern BOOL draw_frame_caption( HDC dc, LPRECT r, UINT uFlags ) DECLSPEC_HIDDEN;
extern BOOL draw_menu_button( HWND hwnd, HDC dc, RECT *r, enum NONCLIENT_BUTTON_TYPE, BOOL down, BOOL grayed ) DECLSPEC_HIDDEN;
extern BOOL draw_frame_menu( HDC dc, RECT *r, UINT flags ) DECLSPEC_HIDDEN;
extern BOOL draw_nc_sys_button( HWND hwnd, HDC hdc, BOOL down ) DECLSPEC_HIDDEN;
extern BOOL draw_rect_edge( HDC hdc, RECT *rc, UINT uType, UINT uFlags, UINT width ) DECLSPEC_HIDDEN;
......
......@@ -770,6 +770,28 @@ static NTSTATUS WINAPI wow64_NtUserCopyImage( void *arg, ULONG size )
return dispatch_callback( NtUserCopyImage, &params32, sizeof(params32) );
}
static NTSTATUS WINAPI wow64_NtUserDrawNonClientButton( void *arg, ULONG size )
{
struct draw_non_client_button_params *params = arg;
struct
{
ULONG hwnd;
ULONG hdc;
enum NONCLIENT_BUTTON_TYPE type;
RECT rect;
BOOL down;
BOOL grayed;
} params32;
params32.hwnd = HandleToUlong( params->hwnd );
params32.hdc = HandleToUlong( params->hdc );
params32.type = params->type;
params32.rect = params->rect;
params32.down = params->down;
params32.grayed = params->grayed;
return dispatch_callback( NtUserDrawNonClientButton, &params32, sizeof(params32) );
}
static NTSTATUS WINAPI wow64_NtUserDrawScrollBar( void *arg, ULONG size )
{
struct draw_scroll_bar_params *params = arg;
......@@ -1073,6 +1095,7 @@ user_callback user_callbacks[] =
wow64_NtUserCallWinProc,
wow64_NtUserCallWindowsHook,
wow64_NtUserCopyImage,
wow64_NtUserDrawNonClientButton,
wow64_NtUserDrawScrollBar,
wow64_NtUserDrawText,
wow64_NtUserFreeCachedClipboardData,
......
......@@ -34,6 +34,7 @@ enum
NtUserCallWinProc,
NtUserCallWindowsHook,
NtUserCopyImage,
NtUserDrawNonClientButton,
NtUserDrawScrollBar,
NtUserDrawText,
NtUserFreeCachedClipboardData,
......@@ -420,6 +421,17 @@ struct set_clipboard_params
UINT seqno;
};
/* NtUserNonClientButton params */
struct draw_non_client_button_params
{
HWND hwnd;
HDC hdc;
enum NONCLIENT_BUTTON_TYPE type;
RECT rect;
BOOL down;
BOOL grayed;
};
/* NtUserDrawScrollBar params */
struct draw_scroll_bar_params
{
......
......@@ -4789,9 +4789,19 @@ struct SCROLL_TRACKING_INFO
enum SCROLL_HITTEST hit_test; /* Hit Test code of the last button-down event */
};
enum NONCLIENT_BUTTON_TYPE
{
MENU_CLOSE_BUTTON, /* Menu close button */
MENU_MIN_BUTTON, /* Menu min button */
MENU_MAX_BUTTON, /* Menu max button */
MENU_RESTORE_BUTTON, /* Menu restore button */
MENU_HELP_BUTTON, /* Menu help button */
};
struct user_api_hook
{
LRESULT (WINAPI *pDefDlgProc)(HWND, UINT, WPARAM, LPARAM, BOOL);
void (WINAPI *pNonClientButtonDraw)(HWND, HDC, enum NONCLIENT_BUTTON_TYPE, RECT, BOOL, BOOL);
void (WINAPI *pScrollBarDraw)(HWND, HDC, INT, enum SCROLL_HITTEST,
const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT,
INT, INT, INT, BOOL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment