Add theming for the rebar control.
This commit is contained in:
parent
25464ceef5
commit
36258675ad
|
@ -102,6 +102,8 @@
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "commctrl.h"
|
#include "commctrl.h"
|
||||||
#include "comctl32.h"
|
#include "comctl32.h"
|
||||||
|
#include "uxtheme.h"
|
||||||
|
#include "tmschema.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(rebar);
|
WINE_DEFAULT_DEBUG_CHANNEL(rebar);
|
||||||
|
@ -184,6 +186,7 @@ typedef struct
|
||||||
HFONT hFont; /* handle to the rebar's font */
|
HFONT hFont; /* handle to the rebar's font */
|
||||||
SIZE imageSize; /* image size (image list) */
|
SIZE imageSize; /* image size (image list) */
|
||||||
DWORD dwStyle; /* window style */
|
DWORD dwStyle; /* window style */
|
||||||
|
DWORD orgStyle; /* original style (dwStyle may change) */
|
||||||
SIZE calcSize; /* calculated rebar size */
|
SIZE calcSize; /* calculated rebar size */
|
||||||
SIZE oldSize; /* previous calculated rebar size */
|
SIZE oldSize; /* previous calculated rebar size */
|
||||||
BOOL bUnicode; /* TRUE if this window is W type */
|
BOOL bUnicode; /* TRUE if this window is W type */
|
||||||
|
@ -322,6 +325,7 @@ static const char *band_maskname[] = {
|
||||||
|
|
||||||
static CHAR line[200];
|
static CHAR line[200];
|
||||||
|
|
||||||
|
static const WCHAR themeClass[] = { 'R','e','b','a','r',0 };
|
||||||
|
|
||||||
static CHAR *
|
static CHAR *
|
||||||
REBAR_FmtStyle( UINT style)
|
REBAR_FmtStyle( UINT style)
|
||||||
|
@ -542,6 +546,7 @@ REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
|
||||||
HFONT hOldFont = 0;
|
HFONT hOldFont = 0;
|
||||||
INT oldBkMode = 0;
|
INT oldBkMode = 0;
|
||||||
NMCUSTOMDRAW nmcd;
|
NMCUSTOMDRAW nmcd;
|
||||||
|
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
|
||||||
|
|
||||||
if (lpBand->fDraw & DRAW_TEXT) {
|
if (lpBand->fDraw & DRAW_TEXT) {
|
||||||
hOldFont = SelectObject (hdc, infoPtr->hFont);
|
hOldFont = SelectObject (hdc, infoPtr->hFont);
|
||||||
|
@ -567,7 +572,19 @@ REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
|
||||||
|
|
||||||
/* draw gripper */
|
/* draw gripper */
|
||||||
if (lpBand->fDraw & DRAW_GRIPPER)
|
if (lpBand->fDraw & DRAW_GRIPPER)
|
||||||
|
{
|
||||||
|
if (theme)
|
||||||
|
{
|
||||||
|
RECT rcGripper = lpBand->rcGripper;
|
||||||
|
int partId = (infoPtr->dwStyle & CCS_VERT) ? RP_GRIPPERVERT : RP_GRIPPER;
|
||||||
|
GetThemeBackgroundExtent (theme, hdc, partId, 0, &rcGripper, &rcGripper);
|
||||||
|
OffsetRect (&rcGripper, lpBand->rcGripper.left - rcGripper.left,
|
||||||
|
lpBand->rcGripper.top - rcGripper.top);
|
||||||
|
DrawThemeBackground (theme, hdc, partId, 0, &rcGripper, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
|
DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
|
||||||
|
}
|
||||||
|
|
||||||
/* draw caption image */
|
/* draw caption image */
|
||||||
if (lpBand->fDraw & DRAW_IMAGE) {
|
if (lpBand->fDraw & DRAW_IMAGE) {
|
||||||
|
@ -603,6 +620,19 @@ REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsRectEmpty(&lpBand->rcChevron))
|
if (!IsRectEmpty(&lpBand->rcChevron))
|
||||||
|
{
|
||||||
|
if (theme)
|
||||||
|
{
|
||||||
|
int stateId;
|
||||||
|
if (lpBand->fDraw & DRAW_CHEVRONPUSHED)
|
||||||
|
stateId = CHEVS_PRESSED;
|
||||||
|
else if (lpBand->fDraw & DRAW_CHEVRONHOT)
|
||||||
|
stateId = CHEVS_HOT;
|
||||||
|
else
|
||||||
|
stateId = CHEVS_NORMAL;
|
||||||
|
DrawThemeBackground (theme, hdc, RP_CHEVRON, stateId, &lpBand->rcChevron, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (lpBand->fDraw & DRAW_CHEVRONPUSHED)
|
if (lpBand->fDraw & DRAW_CHEVRONPUSHED)
|
||||||
{
|
{
|
||||||
|
@ -617,6 +647,7 @@ REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
|
||||||
else
|
else
|
||||||
REBAR_DrawChevron(hdc, lpBand->rcChevron.left, lpBand->rcChevron.top + 10, COLOR_WINDOWFRAME);
|
REBAR_DrawChevron(hdc, lpBand->rcChevron.left, lpBand->rcChevron.top + 10, COLOR_WINDOWFRAME);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (lpBand->uCDret == (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW)) {
|
if (lpBand->uCDret == (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW)) {
|
||||||
nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
|
nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
|
||||||
|
@ -2201,8 +2232,11 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
|
||||||
UINT i;
|
UINT i;
|
||||||
INT oldrow;
|
INT oldrow;
|
||||||
HDC hdc = (HDC)wParam;
|
HDC hdc = (HDC)wParam;
|
||||||
RECT rect;
|
RECT rect, cr;
|
||||||
COLORREF old = CLR_NONE, new;
|
COLORREF old = CLR_NONE, new;
|
||||||
|
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
|
||||||
|
|
||||||
|
GetClientRect (infoPtr->hwndSelf, &cr);
|
||||||
|
|
||||||
oldrow = -1;
|
oldrow = -1;
|
||||||
for(i=0; i<infoPtr->uNumBands; i++) {
|
for(i=0; i<infoPtr->uNumBands; i++) {
|
||||||
|
@ -2218,11 +2252,17 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
|
||||||
if (infoPtr->dwStyle & CCS_VERT) {
|
if (infoPtr->dwStyle & CCS_VERT) {
|
||||||
rcRowSep.right += SEP_WIDTH_SIZE;
|
rcRowSep.right += SEP_WIDTH_SIZE;
|
||||||
rcRowSep.bottom = infoPtr->calcSize.cy;
|
rcRowSep.bottom = infoPtr->calcSize.cy;
|
||||||
|
if (theme)
|
||||||
|
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcRowSep, EDGE_ETCHED, BF_RIGHT, NULL);
|
||||||
|
else
|
||||||
DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_RIGHT);
|
DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_RIGHT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rcRowSep.bottom += SEP_WIDTH_SIZE;
|
rcRowSep.bottom += SEP_WIDTH_SIZE;
|
||||||
rcRowSep.right = infoPtr->calcSize.cx;
|
rcRowSep.right = infoPtr->calcSize.cx;
|
||||||
|
if (theme)
|
||||||
|
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcRowSep, EDGE_ETCHED, BF_BOTTOM, NULL);
|
||||||
|
else
|
||||||
DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_BOTTOM);
|
DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_BOTTOM);
|
||||||
}
|
}
|
||||||
TRACE ("drawing band separator bottom (%ld,%ld)-(%ld,%ld)\n",
|
TRACE ("drawing band separator bottom (%ld,%ld)-(%ld,%ld)\n",
|
||||||
|
@ -2237,10 +2277,16 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
|
||||||
rcSep = lpBand->rcBand;
|
rcSep = lpBand->rcBand;
|
||||||
if (infoPtr->dwStyle & CCS_VERT) {
|
if (infoPtr->dwStyle & CCS_VERT) {
|
||||||
rcSep.bottom += SEP_WIDTH_SIZE;
|
rcSep.bottom += SEP_WIDTH_SIZE;
|
||||||
|
if (theme)
|
||||||
|
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_BOTTOM, NULL);
|
||||||
|
else
|
||||||
DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOM);
|
DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOM);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rcSep.right += SEP_WIDTH_SIZE;
|
rcSep.right += SEP_WIDTH_SIZE;
|
||||||
|
if (theme)
|
||||||
|
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_RIGHT, NULL);
|
||||||
|
else
|
||||||
DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_RIGHT);
|
DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_RIGHT);
|
||||||
}
|
}
|
||||||
TRACE("drawing band separator right (%ld,%ld)-(%ld,%ld)\n",
|
TRACE("drawing band separator right (%ld,%ld)-(%ld,%ld)\n",
|
||||||
|
@ -2267,9 +2313,18 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
|
||||||
new = RGB(0,128,0);
|
new = RGB(0,128,0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
old = SetBkColor (hdc, new);
|
|
||||||
|
|
||||||
rect = lpBand->rcBand;
|
rect = lpBand->rcBand;
|
||||||
|
|
||||||
|
if (theme)
|
||||||
|
{
|
||||||
|
/* When themed, the background color is ignored (but not a
|
||||||
|
* background bitmap */
|
||||||
|
DrawThemeBackground (theme, hdc, 0, 0, &cr, &rect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
old = SetBkColor (hdc, new);
|
||||||
TRACE("%s background color=0x%06lx, band (%ld,%ld)-(%ld,%ld), clip (%ld,%ld)-(%ld,%ld)\n",
|
TRACE("%s background color=0x%06lx, band (%ld,%ld)-(%ld,%ld), clip (%ld,%ld)-(%ld,%ld)\n",
|
||||||
(lpBand->clrBack == CLR_NONE) ? "none" :
|
(lpBand->clrBack == CLR_NONE) ? "none" :
|
||||||
((lpBand->clrBack == CLR_DEFAULT) ? "dft" : ""),
|
((lpBand->clrBack == CLR_DEFAULT) ? "dft" : ""),
|
||||||
|
@ -2282,6 +2337,7 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
|
||||||
if (lpBand->clrBack != CLR_NONE)
|
if (lpBand->clrBack != CLR_NONE)
|
||||||
SetBkColor (hdc, old);
|
SetBkColor (hdc, old);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3759,6 +3815,7 @@ REBAR_Create (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LPCREATESTRUCTW cs = (LPCREATESTRUCTW) lParam;
|
LPCREATESTRUCTW cs = (LPCREATESTRUCTW) lParam;
|
||||||
RECT wnrc1, clrc1;
|
RECT wnrc1, clrc1;
|
||||||
|
HTHEME theme;
|
||||||
|
|
||||||
if (TRACE_ON(rebar)) {
|
if (TRACE_ON(rebar)) {
|
||||||
GetWindowRect(infoPtr->hwndSelf, &wnrc1);
|
GetWindowRect(infoPtr->hwndSelf, &wnrc1);
|
||||||
|
@ -3770,6 +3827,13 @@ REBAR_Create (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("created!\n");
|
TRACE("created!\n");
|
||||||
|
|
||||||
|
if ((theme = OpenThemeData (infoPtr->hwndSelf, themeClass)))
|
||||||
|
{
|
||||||
|
/* native seems to clear WS_BORDER when themed */
|
||||||
|
infoPtr->dwStyle &= ~WS_BORDER;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3808,6 +3872,8 @@ REBAR_Destroy (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
if(infoPtr->hDefaultFont) DeleteObject (infoPtr->hDefaultFont);
|
if(infoPtr->hDefaultFont) DeleteObject (infoPtr->hDefaultFont);
|
||||||
SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
|
SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
|
||||||
|
|
||||||
|
CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));
|
||||||
|
|
||||||
/* free rebar info data */
|
/* free rebar info data */
|
||||||
Free (infoPtr);
|
Free (infoPtr);
|
||||||
TRACE("destroyed!\n");
|
TRACE("destroyed!\n");
|
||||||
|
@ -4051,10 +4117,15 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
inline static LRESULT
|
inline static LRESULT
|
||||||
REBAR_NCCalcSize (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
REBAR_NCCalcSize (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
HTHEME theme;
|
||||||
if (infoPtr->dwStyle & WS_BORDER) {
|
if (infoPtr->dwStyle & WS_BORDER) {
|
||||||
InflateRect((LPRECT)lParam, -GetSystemMetrics(SM_CXEDGE),
|
InflateRect((LPRECT)lParam, -GetSystemMetrics(SM_CXEDGE),
|
||||||
-GetSystemMetrics(SM_CYEDGE));
|
-GetSystemMetrics(SM_CYEDGE));
|
||||||
}
|
}
|
||||||
|
else if ((theme = GetWindowTheme (infoPtr->hwndSelf)))
|
||||||
|
{
|
||||||
|
((LPRECT)lParam)->top++;
|
||||||
|
}
|
||||||
TRACE("new client=(%ld,%ld)-(%ld,%ld)\n",
|
TRACE("new client=(%ld,%ld)-(%ld,%ld)\n",
|
||||||
((LPRECT)lParam)->left, ((LPRECT)lParam)->top,
|
((LPRECT)lParam)->left, ((LPRECT)lParam)->top,
|
||||||
((LPRECT)lParam)->right, ((LPRECT)lParam)->bottom);
|
((LPRECT)lParam)->right, ((LPRECT)lParam)->bottom);
|
||||||
|
@ -4117,6 +4188,8 @@ REBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;
|
infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;
|
||||||
|
|
||||||
|
/* Stow away the original style */
|
||||||
|
infoPtr->orgStyle = cs->style;
|
||||||
/* add necessary styles to the requested styles */
|
/* add necessary styles to the requested styles */
|
||||||
infoPtr->dwStyle = cs->style | WS_VISIBLE | CCS_TOP;
|
infoPtr->dwStyle = cs->style | WS_VISIBLE | CCS_TOP;
|
||||||
SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle);
|
SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle);
|
||||||
|
@ -4200,6 +4273,7 @@ REBAR_NCPaint (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
RECT rcWindow;
|
RECT rcWindow;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
HTHEME theme;
|
||||||
|
|
||||||
if (infoPtr->dwStyle & WS_MINIMIZE)
|
if (infoPtr->dwStyle & WS_MINIMIZE)
|
||||||
return 0; /* Nothing to do */
|
return 0; /* Nothing to do */
|
||||||
|
@ -4217,6 +4291,19 @@ REBAR_NCPaint (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
|
DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
|
||||||
ReleaseDC( infoPtr->hwndSelf, hdc );
|
ReleaseDC( infoPtr->hwndSelf, hdc );
|
||||||
}
|
}
|
||||||
|
else if ((theme = GetWindowTheme (infoPtr->hwndSelf)))
|
||||||
|
{
|
||||||
|
/* adjust rectangle and draw the necessary edge */
|
||||||
|
if (!(hdc = GetDCEx( infoPtr->hwndSelf, 0, DCX_USESTYLE | DCX_WINDOW )))
|
||||||
|
return 0;
|
||||||
|
GetWindowRect (infoPtr->hwndSelf, &rcWindow);
|
||||||
|
OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
|
||||||
|
TRACE("rect (%ld,%ld)-(%ld,%ld)\n",
|
||||||
|
rcWindow.left, rcWindow.top,
|
||||||
|
rcWindow.right, rcWindow.bottom);
|
||||||
|
DrawThemeEdge (theme, hdc, 0, 0, &rcWindow, BDR_RAISEDINNER, BF_TOP, NULL);
|
||||||
|
ReleaseDC( infoPtr->hwndSelf, hdc );
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4456,11 +4543,25 @@ REBAR_StyleChanged (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
TRACE("current style=%08lx, styleOld=%08lx, style being set to=%08lx\n",
|
TRACE("current style=%08lx, styleOld=%08lx, style being set to=%08lx\n",
|
||||||
infoPtr->dwStyle, ss->styleOld, ss->styleNew);
|
infoPtr->dwStyle, ss->styleOld, ss->styleNew);
|
||||||
infoPtr->dwStyle = ss->styleNew;
|
infoPtr->orgStyle = infoPtr->dwStyle = ss->styleNew;
|
||||||
|
if (GetWindowTheme (infoPtr->hwndSelf))
|
||||||
|
infoPtr->dwStyle &= ~WS_BORDER;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* update theme after a WM_THEMECHANGED message */
|
||||||
|
static LRESULT theme_changed (REBAR_INFO* infoPtr)
|
||||||
|
{
|
||||||
|
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
|
||||||
|
CloseThemeData (theme);
|
||||||
|
theme = OpenThemeData (infoPtr->hwndSelf, themeClass);
|
||||||
|
/* WS_BORDER disappears when theming is enabled and reappears when
|
||||||
|
* disabled... */
|
||||||
|
infoPtr->dwStyle &= ~WS_BORDER;
|
||||||
|
infoPtr->dwStyle |= theme ? 0 : (infoPtr->orgStyle & WS_BORDER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT
|
static LRESULT
|
||||||
REBAR_WindowPosChanged (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
REBAR_WindowPosChanged (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
|
@ -4691,6 +4792,9 @@ REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_STYLECHANGED:
|
case WM_STYLECHANGED:
|
||||||
return REBAR_StyleChanged (infoPtr, wParam, lParam);
|
return REBAR_StyleChanged (infoPtr, wParam, lParam);
|
||||||
|
|
||||||
|
case WM_THEMECHANGED:
|
||||||
|
return theme_changed (infoPtr);
|
||||||
|
|
||||||
/* case WM_SYSCOLORCHANGE: supported according to ControlSpy */
|
/* case WM_SYSCOLORCHANGE: supported according to ControlSpy */
|
||||||
/* "Applications that have brushes using the existing system colors
|
/* "Applications that have brushes using the existing system colors
|
||||||
should delete those brushes and recreate them using the new
|
should delete those brushes and recreate them using the new
|
||||||
|
|
Loading…
Reference in New Issue