diff options
Diffstat (limited to 'win/ttkWinMonitor.c')
-rw-r--r-- | win/ttkWinMonitor.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/win/ttkWinMonitor.c b/win/ttkWinMonitor.c new file mode 100644 index 0000000..25c9c0c --- /dev/null +++ b/win/ttkWinMonitor.c @@ -0,0 +1,158 @@ +#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; +} |