1/* $Id$ 2 */ 3 4#ifdef _MSC_VER 5#define WIN32_LEAN_AND_MEAN 6#endif 7 8#include <tkWinInt.h> 9#include "ttk/ttkTheme.h" 10 11#if !defined(WM_THEMECHANGED) 12#define WM_THEMECHANGED 0x031A 13#endif 14 15static LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); 16 17/* 18 * RegisterSystemColors -- 19 * Register all known Windows system colors (as per GetSysColor) as Tk 20 * named colors. 21 */ 22 23typedef struct { 24 const char *name; 25 int index; 26} SystemColorEntry; 27 28static SystemColorEntry sysColors[] = { 29 { "System3dDarkShadow", COLOR_3DDKSHADOW }, 30 { "System3dLight", COLOR_3DLIGHT }, 31 { "SystemActiveBorder", COLOR_ACTIVEBORDER }, 32 { "SystemActiveCaption", COLOR_ACTIVECAPTION }, 33 { "SystemAppWorkspace", COLOR_APPWORKSPACE }, 34 { "SystemBackground", COLOR_BACKGROUND }, 35 { "SystemButtonFace", COLOR_BTNFACE }, 36 { "SystemButtonHighlight", COLOR_BTNHIGHLIGHT }, 37 { "SystemButtonShadow", COLOR_BTNSHADOW }, 38 { "SystemButtonText", COLOR_BTNTEXT }, 39 { "SystemCaptionText", COLOR_CAPTIONTEXT }, 40 { "SystemDisabledText", COLOR_GRAYTEXT }, 41 { "SystemGrayText", COLOR_GRAYTEXT }, 42 { "SystemHighlight", COLOR_HIGHLIGHT }, 43 { "SystemHighlightText", COLOR_HIGHLIGHTTEXT }, 44 { "SystemInactiveBorder", COLOR_INACTIVEBORDER }, 45 { "SystemInactiveCaption", COLOR_INACTIVECAPTION }, 46 { "SystemInactiveCaptionText", COLOR_INACTIVECAPTIONTEXT }, 47 { "SystemInfoBackground", COLOR_INFOBK }, 48 { "SystemInfoText", COLOR_INFOTEXT }, 49 { "SystemMenu", COLOR_MENU }, 50 { "SystemMenuText", COLOR_MENUTEXT }, 51 { "SystemScrollbar", COLOR_SCROLLBAR }, 52 { "SystemWindow", COLOR_WINDOW }, 53 { "SystemWindowFrame", COLOR_WINDOWFRAME }, 54 { "SystemWindowText", COLOR_WINDOWTEXT }, 55 { NULL, 0 } 56}; 57 58static void RegisterSystemColors(Tcl_Interp *interp) 59{ 60 Ttk_ResourceCache cache = Ttk_GetResourceCache(interp); 61 SystemColorEntry *sysColor; 62 63 for (sysColor = sysColors; sysColor->name; ++sysColor) { 64 DWORD pixel = GetSysColor(sysColor->index); 65 XColor colorSpec; 66 colorSpec.red = GetRValue(pixel) * 257; 67 colorSpec.green = GetGValue(pixel) * 257; 68 colorSpec.blue = GetBValue(pixel) * 257; 69 Ttk_RegisterNamedColor(cache, sysColor->name, &colorSpec); 70 } 71} 72 73static HWND 74CreateThemeMonitorWindow(HINSTANCE hinst, Tcl_Interp *interp) 75{ 76 WNDCLASSEX wc; 77 HWND hwnd = NULL; 78 TCHAR title[32] = TEXT("TtkMonitorWindow"); 79 TCHAR name[32] = TEXT("TtkMonitorClass"); 80 81 wc.cbSize = sizeof(WNDCLASSEX); 82 wc.style = CS_HREDRAW | CS_VREDRAW; 83 wc.lpfnWndProc = (WNDPROC)WndProc; 84 wc.cbClsExtra = 0; 85 wc.cbWndExtra = 0; 86 wc.hInstance = hinst; 87 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 88 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 89 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 90 wc.hbrBackground = (HBRUSH)COLOR_WINDOW; 91 wc.lpszMenuName = name; 92 wc.lpszClassName = name; 93 94 if (RegisterClassEx(&wc)) { 95 hwnd = CreateWindow( name, title, WS_OVERLAPPEDWINDOW, 96 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 97 NULL, NULL, hinst, NULL ); 98 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG)interp); 99 ShowWindow(hwnd, SW_HIDE); 100 UpdateWindow(hwnd); 101 } 102 return hwnd; 103} 104 105static void 106DestroyThemeMonitorWindow(void *clientData) 107{ 108 HWND hwnd = (HWND)clientData; 109 DestroyWindow(hwnd); 110} 111 112static LRESULT WINAPI 113WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) 114{ 115 Tcl_Interp *interp = (Tcl_Interp *)GetWindowLongPtr(hwnd, GWLP_USERDATA); 116 Ttk_Theme theme; 117 118 switch (msg) { 119 case WM_DESTROY: 120 break; 121 122 case WM_SYSCOLORCHANGE: 123 RegisterSystemColors(interp); 124 break; 125 126 case WM_THEMECHANGED: 127 /* 128 * Reset the application theme to 'xpnative' if present, 129 * which will in turn fall back to 'winnative' if XP theming 130 * is disabled. 131 */ 132 133 theme = Ttk_GetTheme(interp, "xpnative"); 134 if (theme) { 135 Ttk_UseTheme(interp, theme); 136 /* @@@ What to do about errors here? */ 137 } 138 break; 139 } 140 return DefWindowProc(hwnd, msg, wp, lp); 141} 142 143/* 144 * Windows-specific platform initialization: 145 */ 146 147MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd); 148MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd); 149 150MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp) 151{ 152 HWND hwnd; 153 154 hwnd = CreateThemeMonitorWindow(Tk_GetHINSTANCE(), interp); 155 Ttk_RegisterCleanup(interp, (ClientData)hwnd, DestroyThemeMonitorWindow); 156 157 TtkWinTheme_Init(interp, hwnd); 158 TtkXPTheme_Init(interp, hwnd); 159 160 return TCL_OK; 161} 162