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); ...@@ -72,6 +72,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
static struct user_api_hook original_user_api = static struct user_api_hook original_user_api =
{ {
USER_DefDlgProc, USER_DefDlgProc,
USER_NonClientButtonDraw,
USER_ScrollBarDraw, USER_ScrollBarDraw,
USER_ScrollBarProc, USER_ScrollBarProc,
}; };
......
...@@ -172,3 +172,51 @@ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) ...@@ -172,3 +172,51 @@ LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam )
} }
return 0; 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, ...@@ -104,6 +104,13 @@ static NTSTATUS WINAPI User32CopyImage( const struct copy_image_params *params,
return HandleToUlong( ret ); 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 ) static NTSTATUS WINAPI User32DrawScrollBar( const struct draw_scroll_bar_params *params, ULONG size )
{ {
RECT rect = params->rect; RECT rect = params->rect;
...@@ -200,6 +207,7 @@ static const void *kernel_callback_table[NtUserCallCount] = ...@@ -200,6 +207,7 @@ static const void *kernel_callback_table[NtUserCallCount] =
User32CallWindowProc, User32CallWindowProc,
User32CallWindowsHook, User32CallWindowsHook,
User32CopyImage, User32CopyImage,
User32DrawNonClientButton,
User32DrawScrollBar, User32DrawScrollBar,
User32DrawText, User32DrawText,
User32FreeCachedClipboardData, User32FreeCachedClipboardData,
......
...@@ -158,6 +158,7 @@ extern BOOL get_icon_size( HICON handle, SIZE *size ) DECLSPEC_HIDDEN; ...@@ -158,6 +158,7 @@ extern BOOL get_icon_size( HICON handle, SIZE *size ) DECLSPEC_HIDDEN;
extern struct user_api_hook *user_api 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_DefDlgProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
LRESULT WINAPI USER_ScrollBarProc(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, void WINAPI USER_ScrollBarDraw(HWND, HDC, INT, enum SCROLL_HITTEST,
const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT, const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT,
INT, INT, INT, BOOL) DECLSPEC_HIDDEN; INT, INT, INT, BOOL) DECLSPEC_HIDDEN;
......
...@@ -14,6 +14,7 @@ C_SRCS = \ ...@@ -14,6 +14,7 @@ C_SRCS = \
scrollbar.c \ scrollbar.c \
stylemap.c \ stylemap.c \
system.c \ system.c \
uxini.c uxini.c \
window.c
RC_SRCS = version.rc RC_SRCS = version.rc
...@@ -1245,6 +1245,7 @@ BOOL WINAPI ThemeHooksInstall(void) ...@@ -1245,6 +1245,7 @@ BOOL WINAPI ThemeHooksInstall(void)
struct user_api_hook hooks; struct user_api_hook hooks;
hooks.pDefDlgProc = UXTHEME_DefDlgProc; hooks.pDefDlgProc = UXTHEME_DefDlgProc;
hooks.pNonClientButtonDraw = UXTHEME_NonClientButtonDraw;
hooks.pScrollBarDraw = UXTHEME_ScrollBarDraw; hooks.pScrollBarDraw = UXTHEME_ScrollBarDraw;
hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc; hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc;
return RegisterUserApiHook(&hooks, &user_api); return RegisterUserApiHook(&hooks, &user_api);
......
...@@ -107,6 +107,8 @@ extern void UXTHEME_UninitSystem(void) DECLSPEC_HIDDEN; ...@@ -107,6 +107,8 @@ extern void UXTHEME_UninitSystem(void) DECLSPEC_HIDDEN;
extern struct user_api_hook user_api 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; 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, void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTEST hit_test,
const struct SCROLL_TRACKING_INFO *tracking_info, const struct SCROLL_TRACKING_INFO *tracking_info,
BOOL draw_arrows, BOOL draw_interior, RECT *rect, UINT enable_flags, 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 ) ...@@ -1351,6 +1351,22 @@ BOOL draw_frame_caption( HDC dc, RECT *r, UINT flags )
return TRUE; 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 ) BOOL draw_frame_menu( HDC dc, RECT *r, UINT flags )
{ {
RECT rect; RECT rect;
......
...@@ -2221,7 +2221,7 @@ static void draw_popup_arrow( HDC hdc, RECT rect, UINT arrow_width, UINT arrow_h ...@@ -2221,7 +2221,7 @@ static void draw_popup_arrow( HDC hdc, RECT rect, UINT arrow_width, UINT arrow_h
NtGdiDeleteObjectApp( mem_hdc ); 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 ) struct menu *menu, HWND owner, UINT odaction )
{ {
int w = rect->right - rect->left; int w = rect->right - rect->left;
...@@ -2236,7 +2236,8 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect, ...@@ -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 */ /* Check if there is a magic menu item associated with this item */
if (IS_MAGIC_BITMAP( bmp_to_draw )) if (IS_MAGIC_BITMAP( bmp_to_draw ))
{ {
UINT flags = 0; BOOL down = FALSE, grayed = FALSE;
enum NONCLIENT_BUTTON_TYPE type;
WCHAR bmchr = 0; WCHAR bmchr = 0;
RECT r; RECT r;
...@@ -2262,19 +2263,21 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect, ...@@ -2262,19 +2263,21 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect,
} }
goto got_bitmap; goto got_bitmap;
case (INT_PTR)HBMMENU_MBAR_RESTORE: case (INT_PTR)HBMMENU_MBAR_RESTORE:
flags = DFCS_CAPTIONRESTORE; type = MENU_RESTORE_BUTTON;
break; break;
case (INT_PTR)HBMMENU_MBAR_MINIMIZE: case (INT_PTR)HBMMENU_MBAR_MINIMIZE:
flags = DFCS_CAPTIONMIN; type = MENU_MIN_BUTTON;
break; break;
case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D: case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D:
flags = DFCS_CAPTIONMIN | DFCS_INACTIVE; type = MENU_MIN_BUTTON;
grayed = TRUE;
break; break;
case (INT_PTR)HBMMENU_MBAR_CLOSE: case (INT_PTR)HBMMENU_MBAR_CLOSE:
flags = DFCS_CAPTIONCLOSE; type = MENU_CLOSE_BUTTON;
break; break;
case (INT_PTR)HBMMENU_MBAR_CLOSE_D: case (INT_PTR)HBMMENU_MBAR_CLOSE_D:
flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE; type = MENU_CLOSE_BUTTON;
grayed = TRUE;
break; break;
case (INT_PTR)HBMMENU_CALLBACK: case (INT_PTR)HBMMENU_CALLBACK:
{ {
...@@ -2333,8 +2336,8 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect, ...@@ -2333,8 +2336,8 @@ static void draw_bitmap_item( HDC hdc, struct menu_item *item, const RECT *rect,
{ {
r = *rect; r = *rect;
InflateRect( &r, -1, -1 ); InflateRect( &r, -1, -1 );
if (item->fState & MF_HILITE) flags |= DFCS_PUSHED; if (item->fState & MF_HILITE) down = TRUE;
draw_frame_caption( hdc, &r, flags ); draw_menu_button( hwnd, hdc, &r, type, down, grayed );
} }
return; return;
} }
...@@ -2605,7 +2608,7 @@ static void draw_menu_item( HWND hwnd, struct menu *menu, HWND owner, HDC hdc, ...@@ -2605,7 +2608,7 @@ static void draw_menu_item( HWND hwnd, struct menu *menu, HWND owner, HDC hdc,
POINT origorg; POINT origorg;
/* some applications make this assumption on the DC's origin */ /* some applications make this assumption on the DC's origin */
set_viewport_org( hdc, rect.left, rect.top, &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 ); set_viewport_org( hdc, origorg.x, origorg.y, NULL );
} }
/* Draw the popup-menu arrow */ /* Draw the popup-menu arrow */
...@@ -2621,7 +2624,7 @@ static void draw_menu_item( HWND hwnd, struct menu *menu, HWND owner, HDC hdc, ...@@ -2621,7 +2624,7 @@ static void draw_menu_item( HWND hwnd, struct menu *menu, HWND owner, HDC hdc,
POINT origorg; POINT origorg;
set_viewport_org( hdc, rect.left, rect.top, &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); set_viewport_org( hdc, origorg.x, origorg.y, NULL);
} }
/* process text if present */ /* process text if present */
......
...@@ -241,7 +241,7 @@ extern void register_window_surface( struct window_surface *old, ...@@ -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, extern LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
BOOL ansi ) DECLSPEC_HIDDEN; BOOL ansi ) DECLSPEC_HIDDEN;
extern LRESULT desktop_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) 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_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_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; 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 ) ...@@ -770,6 +770,28 @@ static NTSTATUS WINAPI wow64_NtUserCopyImage( void *arg, ULONG size )
return dispatch_callback( NtUserCopyImage, &params32, sizeof(params32) ); 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 ) static NTSTATUS WINAPI wow64_NtUserDrawScrollBar( void *arg, ULONG size )
{ {
struct draw_scroll_bar_params *params = arg; struct draw_scroll_bar_params *params = arg;
...@@ -1073,6 +1095,7 @@ user_callback user_callbacks[] = ...@@ -1073,6 +1095,7 @@ user_callback user_callbacks[] =
wow64_NtUserCallWinProc, wow64_NtUserCallWinProc,
wow64_NtUserCallWindowsHook, wow64_NtUserCallWindowsHook,
wow64_NtUserCopyImage, wow64_NtUserCopyImage,
wow64_NtUserDrawNonClientButton,
wow64_NtUserDrawScrollBar, wow64_NtUserDrawScrollBar,
wow64_NtUserDrawText, wow64_NtUserDrawText,
wow64_NtUserFreeCachedClipboardData, wow64_NtUserFreeCachedClipboardData,
......
...@@ -34,6 +34,7 @@ enum ...@@ -34,6 +34,7 @@ enum
NtUserCallWinProc, NtUserCallWinProc,
NtUserCallWindowsHook, NtUserCallWindowsHook,
NtUserCopyImage, NtUserCopyImage,
NtUserDrawNonClientButton,
NtUserDrawScrollBar, NtUserDrawScrollBar,
NtUserDrawText, NtUserDrawText,
NtUserFreeCachedClipboardData, NtUserFreeCachedClipboardData,
...@@ -420,6 +421,17 @@ struct set_clipboard_params ...@@ -420,6 +421,17 @@ struct set_clipboard_params
UINT seqno; 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 */ /* NtUserDrawScrollBar params */
struct draw_scroll_bar_params struct draw_scroll_bar_params
{ {
......
...@@ -4789,9 +4789,19 @@ struct SCROLL_TRACKING_INFO ...@@ -4789,9 +4789,19 @@ struct SCROLL_TRACKING_INFO
enum SCROLL_HITTEST hit_test; /* Hit Test code of the last button-down event */ 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 struct user_api_hook
{ {
LRESULT (WINAPI *pDefDlgProc)(HWND, UINT, WPARAM, LPARAM, BOOL); 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, void (WINAPI *pScrollBarDraw)(HWND, HDC, INT, enum SCROLL_HITTEST,
const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT, const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, UINT,
INT, INT, INT, BOOL); 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