159 lines
4.3 KiB
C
159 lines
4.3 KiB
C
#ifdef _MSC_VER
|
||
#define WIN32_LEAN_AND_MEAN
|
||
#endif
|
||
|
||
#include <tkWinInt.h>
|
||
#include "ttk/ttkTheme.h"
|
||
|
||
#if !defined(WM_THEMECHANGED)
|
||
#define WM_THEMECHANGED 0x031A
|
||
#endif
|
||
|
||
static LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
|
||
|
||
/*
|
||
* RegisterSystemColors --
|
||
* Register all known Windows system colors (as per GetSysColor) as Tk
|
||
* named colors.
|
||
*/
|
||
|
||
typedef struct {
|
||
const char *name;
|
||
int index;
|
||
} SystemColorEntry;
|
||
|
||
static SystemColorEntry sysColors[] = {
|
||
{ "System3dDarkShadow", COLOR_3DDKSHADOW },
|
||
{ "System3dLight", COLOR_3DLIGHT },
|
||
{ "SystemActiveBorder", COLOR_ACTIVEBORDER },
|
||
{ "SystemActiveCaption", COLOR_ACTIVECAPTION },
|
||
{ "SystemAppWorkspace", COLOR_APPWORKSPACE },
|
||
{ "SystemBackground", COLOR_BACKGROUND },
|
||
{ "SystemButtonFace", COLOR_BTNFACE },
|
||
{ "SystemButtonHighlight", COLOR_BTNHIGHLIGHT },
|
||
{ "SystemButtonShadow", COLOR_BTNSHADOW },
|
||
{ "SystemButtonText", COLOR_BTNTEXT },
|
||
{ "SystemCaptionText", COLOR_CAPTIONTEXT },
|
||
{ "SystemDisabledText", COLOR_GRAYTEXT },
|
||
{ "SystemGrayText", COLOR_GRAYTEXT },
|
||
{ "SystemHighlight", COLOR_HIGHLIGHT },
|
||
{ "SystemHighlightText", COLOR_HIGHLIGHTTEXT },
|
||
{ "SystemInactiveBorder", COLOR_INACTIVEBORDER },
|
||
{ "SystemInactiveCaption", COLOR_INACTIVECAPTION },
|
||
{ "SystemInactiveCaptionText", COLOR_INACTIVECAPTIONTEXT },
|
||
{ "SystemInfoBackground", COLOR_INFOBK },
|
||
{ "SystemInfoText", COLOR_INFOTEXT },
|
||
{ "SystemMenu", COLOR_MENU },
|
||
{ "SystemMenuText", COLOR_MENUTEXT },
|
||
{ "SystemScrollbar", COLOR_SCROLLBAR },
|
||
{ "SystemWindow", COLOR_WINDOW },
|
||
{ "SystemWindowFrame", COLOR_WINDOWFRAME },
|
||
{ "SystemWindowText", COLOR_WINDOWTEXT },
|
||
{ NULL, 0 }
|
||
};
|
||
|
||
static void RegisterSystemColors(Tcl_Interp *interp)
|
||
{
|
||
Ttk_ResourceCache cache = Ttk_GetResourceCache(interp);
|
||
SystemColorEntry *sysColor;
|
||
|
||
for (sysColor = sysColors; sysColor->name; ++sysColor) {
|
||
DWORD pixel = GetSysColor(sysColor->index);
|
||
XColor colorSpec;
|
||
colorSpec.red = GetRValue(pixel) * 257;
|
||
colorSpec.green = GetGValue(pixel) * 257;
|
||
colorSpec.blue = GetBValue(pixel) * 257;
|
||
Ttk_RegisterNamedColor(cache, sysColor->name, &colorSpec);
|
||
}
|
||
}
|
||
|
||
static HWND
|
||
CreateThemeMonitorWindow(HINSTANCE hinst, Tcl_Interp *interp)
|
||
{
|
||
WNDCLASSEX wc;
|
||
HWND hwnd = NULL;
|
||
TCHAR title[32] = TEXT("TtkMonitorWindow");
|
||
TCHAR name[32] = TEXT("TtkMonitorClass");
|
||
|
||
wc.cbSize = sizeof(WNDCLASSEX);
|
||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||
wc.lpfnWndProc = (WNDPROC)WndProc;
|
||
wc.cbClsExtra = 0;
|
||
wc.cbWndExtra = 0;
|
||
wc.hInstance = hinst;
|
||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||
wc.lpszMenuName = name;
|
||
wc.lpszClassName = name;
|
||
|
||
if (RegisterClassEx(&wc)) {
|
||
hwnd = CreateWindow( name, title, WS_OVERLAPPEDWINDOW,
|
||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||
NULL, NULL, hinst, NULL );
|
||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)interp);
|
||
ShowWindow(hwnd, SW_HIDE);
|
||
UpdateWindow(hwnd);
|
||
}
|
||
return hwnd;
|
||
}
|
||
|
||
static void
|
||
DestroyThemeMonitorWindow(void *clientData)
|
||
{
|
||
HWND hwnd = (HWND)clientData;
|
||
DestroyWindow(hwnd);
|
||
}
|
||
|
||
static LRESULT WINAPI
|
||
WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
||
{
|
||
Tcl_Interp *interp = (Tcl_Interp *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||
Ttk_Theme theme;
|
||
|
||
switch (msg) {
|
||
case WM_DESTROY:
|
||
break;
|
||
|
||
case WM_SYSCOLORCHANGE:
|
||
RegisterSystemColors(interp);
|
||
break;
|
||
|
||
case WM_THEMECHANGED:
|
||
/*
|
||
* Reset the application theme to 'xpnative' if present,
|
||
* which will in turn fall back to 'winnative' if XP theming
|
||
* is disabled.
|
||
*/
|
||
|
||
theme = Ttk_GetTheme(interp, "xpnative");
|
||
if (theme) {
|
||
Ttk_UseTheme(interp, theme);
|
||
/* @@@ What to do about errors here? */
|
||
}
|
||
break;
|
||
}
|
||
return DefWindowProc(hwnd, msg, wp, lp);
|
||
}
|
||
|
||
/*
|
||
* Windows-specific platform initialization:
|
||
*/
|
||
|
||
MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd);
|
||
MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd);
|
||
|
||
MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp)
|
||
{
|
||
HWND hwnd;
|
||
|
||
hwnd = CreateThemeMonitorWindow(Tk_GetHINSTANCE(), interp);
|
||
Ttk_RegisterCleanup(interp, (ClientData)hwnd, DestroyThemeMonitorWindow);
|
||
|
||
TtkWinTheme_Init(interp, hwnd);
|
||
TtkXPTheme_Init(interp, hwnd);
|
||
|
||
return TCL_OK;
|
||
}
|