[OSK] Make the buttons themed

Our On-Screen Keyboard has a manifest and the buttons (the ones with BS_ICON styles) aren't rendered with the specific theme as it should be but instead it takes the classic theme.

The code relies on NM_CUSTOMDRAW notification, which is more intuitive and efficient than doing owner-drawn operations as NM_CUSTOMDRAW allows the controls to use styles whereas you cannot do it on owner-drawn controls.

CORE-15965
This commit is contained in:
Bișoc George 2019-04-22 15:01:18 +02:00 committed by Hermès BÉLUSCA - MAÏTO
parent 9ce337242b
commit f681bad246
3 changed files with 66 additions and 3 deletions

View file

@ -3,5 +3,5 @@ file(GLOB osk_rc_deps res/*.*)
add_rc_deps(rsrc.rc ${osk_rc_deps})
add_executable(osk main.c settings.c rsrc.rc)
set_module_type(osk win32gui UNICODE)
add_importlibs(osk comdlg32 winmm shell32 user32 gdi32 advapi32 comctl32 msvcrt kernel32 ntdll)
add_importlibs(osk comdlg32 uxtheme winmm shell32 user32 gdi32 advapi32 comctl32 msvcrt kernel32 ntdll)
add_cd_file(TARGET osk DESTINATION reactos/system32 FOR all)

View file

@ -24,6 +24,7 @@ BOOL OSK_DlgCommand(WPARAM wCommand, HWND hWndControl);
BOOL OSK_ReleaseKey(WORD ScanCode);
INT_PTR APIENTRY OSK_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT APIENTRY OSK_ThemeHandler(HWND hDlg, NMCUSTOMDRAW *pNmDraw);
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
/* FUNCTIONS ******************************************************************/
@ -428,6 +429,58 @@ BOOL OSK_ReleaseKey(WORD ScanCode)
return TRUE;
}
/***********************************************************************
*
* OSK_ThemeHandler
*
* Function helper which handles theme drawing of controls
*/
LRESULT APIENTRY OSK_ThemeHandler(HWND hDlg, NMCUSTOMDRAW *pNmDraw)
{
HTHEME hTheme;
HWND hDlgButtonCtrl;
INT iState = PBS_NORMAL;
/* Retrieve the theme handle for the button controls */
hDlgButtonCtrl = pNmDraw->hdr.hwndFrom;
hTheme = GetWindowTheme(hDlgButtonCtrl);
/*
Begin the painting procedures if we retrieved
the theme for control buttons of the dialog.
*/
if (hTheme)
{
/*
The button could be either in normal state or pushed.
Retrieve its state and save to a variable.
*/
if (pNmDraw->uItemState & CDIS_DEFAULT)
{
iState = PBS_DEFAULTED;
}
else if (pNmDraw->uItemState & CDIS_SELECTED)
{
iState = PBS_PRESSED;
}
else if (pNmDraw->uItemState & CDIS_HOT)
{
iState = PBS_HOT;
}
if (IsThemeBackgroundPartiallyTransparent(hTheme, BP_PUSHBUTTON, iState))
{
/* Draw the application if the theme is transparent */
DrawThemeParentBackground(hDlg, pNmDraw->hdc, &pNmDraw->rc);
}
/* Draw it */
DrawThemeBackground(hTheme, pNmDraw->hdc, BP_PUSHBUTTON, iState, &pNmDraw->rc, NULL);
}
return CDRF_SKIPDEFAULT;
}
/***********************************************************************
*
* OSK_DlgProc
@ -444,6 +497,9 @@ INT_PTR APIENTRY OSK_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
OSK_DlgTimer();
return TRUE;
case WM_NOTIFY:
return OSK_ThemeHandler(hDlg, (LPNMCUSTOMDRAW)lParam);
case WM_CTLCOLORSTATIC:
if ((HWND)lParam == GetDlgItem(hDlg, IDC_LED_NUM))
{
@ -567,6 +623,11 @@ INT_PTR APIENTRY OSK_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
}
break;
case WM_THEMECHANGED:
/* Redraw the dialog (and its control buttons) using the new theme */
InvalidateRect(hDlg, NULL, FALSE);
break;
case WM_CLOSE:
OSK_DlgClose();
break;

View file

@ -1,9 +1,9 @@
/*
* PROJECT: ReactOS On-Screen Keyboard
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/osk/osk.h
* PURPOSE: On screen keyboard.
* PROGRAMMERS: Denis ROBERT
* COPYRIGHT: Denis ROBERT
* Copyright 2019 Bișoc George (fraizeraust99 at gmail dot com)
*/
#ifndef _OSK_H
@ -16,6 +16,8 @@
#include <windows.h>
#include <commctrl.h>
#include <debug.h>
#include <uxtheme.h>
#include <vsstyle.h>
#include "main.h"