comparison win/dw.c @ 1536:a71ec02f3b70

Attempt on Windows using DrawThemeTextEx to nicely display text widgets on glass backgrounds. It mostly works but due to using the transparency key it doesn't really look mixed with the glass. More work needs to be done.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 12 Jan 2012 17:21:31 +0000
parents 2913bb58f439
children a4ecef1980db
comparison
equal deleted inserted replaced
1535:2913bb58f439 1536:a71ec02f3b70
105 #endif 105 #endif
106 106
107 #ifdef AEROGLASS 107 #ifdef AEROGLASS
108 HRESULT (WINAPI *_DwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset) = 0; 108 HRESULT (WINAPI *_DwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset) = 0;
109 HRESULT (WINAPI *_DwmIsCompositionEnabled)(BOOL *pfEnabled) = 0; 109 HRESULT (WINAPI *_DwmIsCompositionEnabled)(BOOL *pfEnabled) = 0;
110 HTHEME (WINAPI *_OpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
111 HPAINTBUFFER (WINAPI *_BeginBufferedPaint)(HDC hdcTarget, const RECT *prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS *pPaintParams, HDC *phdc);
112 HRESULT (WINAPI *_BufferedPaintSetAlpha)(HPAINTBUFFER hBufferedPaint, const RECT *prc, BYTE alpha);
113 HRESULT (WINAPI *_DrawThemeTextEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwFlags, LPRECT pRect, const DTTOPTS *pOptions);
114 HRESULT (WINAPI *_EndBufferedPaint)(HPAINTBUFFER hBufferedPaint, BOOL fUpdateTarget);
115 HRESULT (WINAPI *_CloseThemeData)(HTHEME hTheme);
110 BOOL _dw_composition = FALSE; 116 BOOL _dw_composition = FALSE;
111 COLORREF _dw_transparencykey = RGB(200,201,202); 117 COLORREF _dw_transparencykey = RGB(200,201,202);
112 HANDLE hdwm = 0; 118 HANDLE hdwm = 0, huxtheme = 0;
113 #endif 119 #endif
114 120
115 /* 121 /*
116 * MinGW Is missing a bunch of definitions 122 * MinGW Is missing a bunch of definitions
117 * so #define them here... 123 * so #define them here...
3264 return FALSE; 3270 return FALSE;
3265 } 3271 }
3266 return DefWindowProc(hwnd, msg, mp1, mp2); 3272 return DefWindowProc(hwnd, msg, mp1, mp2);
3267 } 3273 }
3268 3274
3275 #ifdef AEROGLASS
3276 /* Window procedure to handle drawing themed text when in composited mode */
3277 BOOL CALLBACK _staticwndproc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
3278 {
3279 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
3280 WNDPROC pOldProc;
3281
3282 if (!cinfo)
3283 return DefWindowProc(hwnd, msg, mp1, mp2);
3284
3285 /* If we don't require themed drawing */
3286 if(cinfo->back != -1 && !_dw_composition || !(GetWindowLongPtr(_toplevel_window(hwnd), GWL_EXSTYLE) & WS_EX_LAYERED))
3287 return _colorwndproc(hwnd, msg, mp1, mp2);
3288
3289 pOldProc = cinfo->pOldProc;
3290
3291 switch(msg)
3292 {
3293 case WM_PAINT:
3294 {
3295 PAINTSTRUCT ps;
3296 HDC hdc = BeginPaint(hwnd, &ps);
3297
3298 if(hdc)
3299 {
3300 /* Figure out how to draw */
3301 HDC hdcPaint = NULL;
3302 RECT rcClient;
3303 LONG_PTR dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
3304 LONG_PTR dwStyleEx = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
3305 HTHEME hTheme = _OpenThemeData(NULL, L"ControlPanelStyle");
3306
3307 GetClientRect(hwnd, &rcClient);
3308
3309 if(hTheme)
3310 {
3311 /* Create an in memory image to draw to */
3312 HPAINTBUFFER hBufferedPaint = _BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, NULL, &hdcPaint);
3313
3314 if(hdcPaint)
3315 {
3316 LONG_PTR dwStaticStyle = dwStyle & 0x1F;
3317 HFONT hFontOld = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
3318 int iLen = GetWindowTextLength(hwnd), fore = _internal_color(cinfo->fore);
3319 DTTOPTS DttOpts = { sizeof(DTTOPTS) };
3320 static HBRUSH hbrush = 0;
3321
3322 /* Make sure we have a transparency brush */
3323 if(!hbrush)
3324 hbrush = CreateSolidBrush(_dw_transparencykey);
3325
3326 /* Fill the background with the transparency color */
3327 FillRect(hdcPaint, &rcClient, hbrush);
3328 _BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00);
3329
3330 /* Setup how we will draw the text */
3331 DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE | DTT_TEXTCOLOR;
3332 DttOpts.crText = cinfo->fore == -1 ? RGB(255, 255, 255) : RGB(DW_RED_VALUE(fore), DW_GREEN_VALUE(fore), DW_BLUE_VALUE(fore));
3333 DttOpts.iGlowSize = 12;
3334
3335 SetBkMode(hdcPaint, TRANSPARENT);
3336
3337 if(hFontOld)
3338 hFontOld = (HFONT)SelectObject(hdcPaint, hFontOld);
3339
3340 /* Make sure there is text to draw */
3341 if(iLen)
3342 {
3343 LPWSTR szText = (LPWSTR)_alloca(sizeof(WCHAR)*(iLen+5));
3344
3345 if(szText)
3346 {
3347 iLen = GetWindowTextW(hwnd, szText, iLen+5);
3348 if(iLen)
3349 {
3350 DWORD dwFlags = DT_WORDBREAK;
3351
3352 switch (dwStaticStyle)
3353 {
3354 case SS_CENTER:
3355 dwFlags |= DT_CENTER;
3356 break;
3357 case SS_RIGHT:
3358 dwFlags |= DT_RIGHT;
3359 break;
3360 case SS_LEFTNOWORDWRAP:
3361 dwFlags &= ~DT_WORDBREAK;
3362 break;
3363 }
3364
3365 if(dwStyle & SS_CENTERIMAGE)
3366 {
3367 dwFlags |= DT_VCENTER;
3368 dwFlags &= ~DT_WORDBREAK;
3369 }
3370
3371
3372 if(dwStyle & SS_ENDELLIPSIS)
3373 dwFlags |= DT_END_ELLIPSIS|DT_MODIFYSTRING;
3374 else if(dwStyle & SS_PATHELLIPSIS)
3375 dwFlags |= DT_PATH_ELLIPSIS|DT_MODIFYSTRING;
3376 else if(dwStyle & SS_WORDELLIPSIS)
3377 dwFlags |= DT_WORD_ELLIPSIS|DT_MODIFYSTRING;
3378
3379 if (dwStyleEx&WS_EX_RIGHT)
3380 dwFlags |= DT_RIGHT;
3381
3382 if(dwStyle & SS_NOPREFIX)
3383 dwFlags |= DT_NOPREFIX;
3384
3385 /* Draw the text! */
3386 _DrawThemeTextEx(hTheme, hdcPaint, 0, 0,
3387 szText, -1, dwFlags, &rcClient, &DttOpts);
3388 }
3389 }
3390 }
3391
3392 /* Cleanup */
3393 if (hFontOld)
3394 SelectObject(hdcPaint, hFontOld);
3395 _EndBufferedPaint(hBufferedPaint, TRUE);
3396 }
3397 _CloseThemeData(hTheme);
3398 }
3399 }
3400
3401 EndPaint(hwnd, &ps);
3402 return TRUE;
3403 }
3404 break;
3405 }
3406
3407 if ( !pOldProc )
3408 return DefWindowProc(hwnd, msg, mp1, mp2);
3409 return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2);
3410 }
3411 #endif
3412
3269 /* Function: _BtProc 3413 /* Function: _BtProc
3270 * Abstract: Subclass procedure for buttons 3414 * Abstract: Subclass procedure for buttons
3271 */ 3415 */
3272 3416
3273 BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2) 3417 BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
3713 si.SuppressExternalCodecs = FALSE; 3857 si.SuppressExternalCodecs = FALSE;
3714 GdiplusStartup(&gdiplusToken, &si, NULL); 3858 GdiplusStartup(&gdiplusToken, &si, NULL);
3715 #endif 3859 #endif
3716 3860
3717 #ifdef AEROGLASS 3861 #ifdef AEROGLASS
3718 /* Attempt to load the Desktop Window Manager library */ 3862 /* Attempt to load the Desktop Window Manager and Theme library */
3719 if((hdwm = LoadLibrary("dwmapi"))) 3863 if((hdwm = LoadLibrary("dwmapi")) && (huxtheme = LoadLibrary("uxtheme")))
3720 { 3864 {
3721 _DwmExtendFrameIntoClientArea = (HRESULT (WINAPI *)(HWND, const MARGINS *))GetProcAddress(hdwm, "DwmExtendFrameIntoClientArea"); 3865 _DwmExtendFrameIntoClientArea = (HRESULT (WINAPI *)(HWND, const MARGINS *))GetProcAddress(hdwm, "DwmExtendFrameIntoClientArea");
3722 if((_DwmIsCompositionEnabled = (HRESULT (WINAPI *)(BOOL *))GetProcAddress(hdwm, "DwmIsCompositionEnabled"))) 3866 if((_DwmIsCompositionEnabled = (HRESULT (WINAPI *)(BOOL *))GetProcAddress(hdwm, "DwmIsCompositionEnabled")))
3723 _DwmIsCompositionEnabled(&_dw_composition); 3867 _DwmIsCompositionEnabled(&_dw_composition);
3724 3868 _OpenThemeData = (HTHEME (WINAPI *)(HWND, LPCWSTR))GetProcAddress(huxtheme, "OpenThemeData");
3725 } 3869 _BeginBufferedPaint = (HPAINTBUFFER (WINAPI *)(HDC, const RECT *, BP_BUFFERFORMAT, BP_PAINTPARAMS *, HDC *))GetProcAddress(huxtheme, "BeginBufferedPaint");
3726 3870 _BufferedPaintSetAlpha = (HRESULT (WINAPI *)(HPAINTBUFFER, const RECT *, BYTE))GetProcAddress(huxtheme, "BufferedPaintSetAlpha");
3871 _DrawThemeTextEx = (HRESULT (WINAPI *)(HTHEME, HDC, int, int, LPCWSTR, int, DWORD, LPRECT, const DTTOPTS *))GetProcAddress(huxtheme, "DrawThemeTextEx");
3872 _EndBufferedPaint = (HRESULT (WINAPI *)(HPAINTBUFFER, BOOL))GetProcAddress(huxtheme, "EndBufferedPaint");
3873 _CloseThemeData = (HRESULT (WINAPI *)(HTHEME))GetProcAddress(huxtheme, "CloseThemeData");
3874 }
3875 /* In case of error close the library if needed */
3876 else if(hdwm)
3877 {
3878 FreeLibrary(hdwm);
3879 hdwm = 0;
3880 }
3727 #endif 3881 #endif
3728 return 0; 3882 return 0;
3729 } 3883 }
3730 3884
3731 static int _dw_main_running = FALSE; 3885 static int _dw_main_running = FALSE;
5490 */ 5644 */
5491 HWND API dw_text_new(char *text, ULONG id) 5645 HWND API dw_text_new(char *text, ULONG id)
5492 { 5646 {
5493 HWND tmp = CreateWindow(STATICCLASSNAME, 5647 HWND tmp = CreateWindow(STATICCLASSNAME,
5494 text, 5648 text,
5495 SS_NOPREFIX | SS_NOTIFY | 5649 SS_NOPREFIX | SS_NOTIFY | WS_VISIBLE |
5496 BS_TEXT | WS_VISIBLE |
5497 WS_CHILD | WS_CLIPCHILDREN, 5650 WS_CHILD | WS_CLIPCHILDREN,
5498 0,0,0,0, 5651 0,0,0,0,
5499 DW_HWND_OBJECT, 5652 DW_HWND_OBJECT,
5500 (HMENU)id, 5653 (HMENU)id,
5501 DWInstance, 5654 DWInstance,
5502 NULL); 5655 NULL);
5656 #ifdef AEROGLASS
5657 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
5658
5659 cinfo->back = cinfo->fore = -1;
5660
5661 cinfo->pOldProc = SubclassWindow(tmp, _staticwndproc);
5662 SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
5663 #endif
5503 dw_window_set_font(tmp, DefaultFont); 5664 dw_window_set_font(tmp, DefaultFont);
5504 dw_window_set_color(tmp, DW_CLR_DEFAULT, DW_RGB_TRANSPARENT); 5665 dw_window_set_color(tmp, DW_CLR_DEFAULT, DW_RGB_TRANSPARENT);
5505 return tmp; 5666 return tmp;
5506 } 5667 }
5507 5668
5513 */ 5674 */
5514 HWND API dw_status_text_new(char *text, ULONG id) 5675 HWND API dw_status_text_new(char *text, ULONG id)
5515 { 5676 {
5516 HWND tmp = CreateWindow(StatusbarClassName, 5677 HWND tmp = CreateWindow(StatusbarClassName,
5517 text, 5678 text,
5518 BS_TEXT | WS_VISIBLE | 5679 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
5519 WS_CHILD | WS_CLIPCHILDREN,
5520 0,0,0,0, 5680 0,0,0,0,
5521 DW_HWND_OBJECT, 5681 DW_HWND_OBJECT,
5522 (HMENU)id, 5682 (HMENU)id,
5523 DWInstance, 5683 DWInstance,
5524 NULL); 5684 NULL);
10377 { 10537 {
10378 OleUninitialize(); 10538 OleUninitialize();
10379 #ifdef AEROGLASS 10539 #ifdef AEROGLASS
10380 /* Free any in use libraries */ 10540 /* Free any in use libraries */
10381 FreeLibrary(hdwm); 10541 FreeLibrary(hdwm);
10542 FreeLibrary(huxtheme);
10382 #endif 10543 #endif
10383 exit(exitcode); 10544 exit(exitcode);
10384 } 10545 }
10385 10546
10386 /* 10547 /*