INTRODUCTION AND RELATED INFORMATION:
I have two dialog boxes created using the resource editor. Since I use Microsoft Visual Studio Express, I had to download a free resource editor to create them. In my program, I have Visual Styles like this:
#include <commctrl.h> #pragma comment( lib, "comctl32.lib") #pragma comment( linker, "/manifestdependency:\"type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \ language='*'\"")
As far as I know, check the box, radio button, and group box to get the text WM_CTLCOLORSTATIC to draw their text.
This is what I encoded for the first and second dialog box:
case WM_CTLCOLORSTATIC: { SetBkMode( (HDC)wParam, TRANSPARENT ); SetTextColor( (HDC)wParam, RGB( 0, 0, 0 ) ); return (INT_PTR)( (HBRUSH)GetStockObject(NULL_BRUSH) ); }
I want these controls to have a transparent text background and the black color of their text.
PROBLEM:
In Windows XP, here is an image of the result for the first dialog:

The group box has blue text and a brown frame, and the check box has everything black. In Windows 7, after running the same program, I get the following:

Here the group field and check box have the correct text color, however, the background of the check box and the border of the group field are incorrect. In my dialog box, I have static controls and they are correctly colored in both Windows 7 and Windows XP.
WHAT HAD THE FOLLOWING:
I looked through the SO archive, but did not find anything that I could use to modify the WM_CTLCOLORSTATIC handler.
I found a workaround that removes visual styles from these controls, so it can achieve the desired result, but I need to keep the visual styles and make the text background transparent, the solution cannot satisfy me.
After looking at the Visual Styles link and a little experiment, I found a workaround for the switch and a checkbox (but not for the group field) with the following code:
case WM_CTLCOLORSTATIC: if( (HWND)lParam == GetDlgItem( hwnd, IDC_RADIO1 ) ) { RECT r; GetClientRect( hwnd, &r ); DrawThemeParentBackground( (HWND)lParam, (HDC)wParam, &r ); } else { SetTextColor( (HDC)wParam, RGB( 0, 0, 0 ) ); SetBkMode( (HDC)wParam, TRANSPARENT ); } return (INT_PTR)( (HBRUSH)GetStockObject(NULL_BRUSH) );
However, I “hit the wall” as follows:
There is a tree structure in my dialog box, and as soon as I select node and press spacebar (or any other key, for that matter), the dialog box bitmap gets on top of my static controls.
After I comment on DrawThemeParentBackground() , recompile and run the program again, everything works fine (when I select the node tree and press spacebar ), but then I am “square one”.
QUESTIONS:
How can I change the WM_CTLCOLORSTATIC handler to fix my problem?
If the above is not possible, can I get the desired effect using NM_CUSTOMDRAW ?
Note:
I think I will have to draw a group box using GDI . If so, I will also agree with this solution, since my main problem is checkbox and radio button .
THE SUGGESTED PROGRAM EXAMPLE CHANGED:
Upon request, I send SSCCE . To create a project, follow these steps:
1.) Create a default Win32 project in Visual Studio.
2.) In stdafx.h copy / paste the following directives below #include <windows.h> :
#include <commctrl.h> #include <Uxtheme.h> #pragma comment( linker, "/manifestdependency:\"type='win32' \ name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \ language='*'\"") #pragma comment( lib, "comctl32.lib") #pragma comment( lib,"Msimg32.lib") // needed for GradientFill(...) API #pragma comment( lib, "UxTheme.lib")
3.) In the resource editor, change the "Add" dialog box by adding 2 radio buttons, 2 flags and the group they belong to (see the above figures, also see what I mean) and add a tree structure control (this element control will "cause" the problem).
4.) In the main cpp file, add a helper function to paint a custom background:
void GradientTriangle( HDC MemDC, LONG x1, LONG y1, LONG x2, LONG y2, LONG x3, LONG y3, COLORREF top, COLORREF bottom ) { TRIVERTEX vertex[3]; vertex[0].x = x1; vertex[0].y = y1; vertex[0].Red = GetRValue(bottom) << 8; vertex[0].Green = GetGValue(bottom) << 8; vertex[0].Blue = GetBValue(bottom) << 8; vertex[0].Alpha = 0x0000; vertex[1].x = x3; vertex[1].y = y3; vertex[1].Red = GetRValue(bottom) << 8; vertex[1].Green = GetGValue(bottom) << 8; vertex[1].Blue = GetBValue(bottom) << 8; vertex[1].Alpha = 0x0000; vertex[2].x = x2; vertex[2].y = y2; vertex[2].Red = GetRValue(top) << 8; vertex[2].Green = GetGValue(top) << 8; vertex[2].Blue = GetBValue(top) << 8; vertex[2].Alpha = 0x0000;
5.) Initiate common controls in _tWinMain :
6.) Insert several elements into the tree structure in WM_INITDIALOG :
case WM_INITDIALOG: { HWND TreeView = GetDlgItem( hDlg, IDC_TREE1 ); // add root item TVINSERTSTRUCT tvis = {0}; tvis.item.mask = TVIF_TEXT; tvis.item.pszText = L"This is root item"; tvis.hInsertAfter = TVI_LAST; tvis.hParent = TVI_ROOT; HTREEITEM hRootItem = reinterpret_cast<HTREEITEM>( SendMessage( TreeView , TVM_INSERTITEM, 0, reinterpret_cast<LPARAM>( &tvis ) ) ); // add firts subitem for the hTreeItem memset( &tvis, 0, sizeof(TVINSERTSTRUCT) ); tvis.item.mask = TVIF_TEXT; tvis.item.pszText = L"This is first subitem"; tvis.hInsertAfter = TVI_LAST; tvis.hParent = hRootItem; HTREEITEM hTreeSubItem1 = reinterpret_cast<HTREEITEM>( SendMessage( TreeView , TVM_INSERTITEM, 0, reinterpret_cast<LPARAM>( &tvis ) ) ); // now we insert second subitem for hRootItem memset( &tvis, 0, sizeof(TVINSERTSTRUCT) ); tvis.item.mask = TVIF_TEXT | TVIF_STATE; // added extra flag tvis.item.pszText = L"This is second subitem"; tvis.hInsertAfter = TVI_LAST; tvis.hParent = hRootItem; HTREEITEM hTreeSubItem2 = reinterpret_cast<HTREEITEM>( SendMessage( TreeView , TVM_INSERTITEM, 0, reinterpret_cast<LPARAM>( &tvis ) ) ); } return (INT_PTR)TRUE;
7.) Draw a custom dialog background:
case WM_ERASEBKGND: { RECT r; GetClientRect( hDlg, &r ); GradientTriangle( (HDC)wParam, r.right, r.bottom - r.top, r.left, r.bottom - r.top, r.left, r.top, RGB( 0x0, 0x0, 0xFF ), RGB( 0xFF, 0xFF, 0x0 ) ); GradientTriangle( (HDC)wParam, r.right, r.bottom - r.top, r.right, r.top, r.left, r.top, RGB( 0xFF, 0x0, 0x0 ), RGB( 0x0, 0xFF, 0x0 ) ); } return TRUE;
8.) Add a handler for WM_CTLCOLORSTATIC :
case WM_CTLCOLORSTATIC: if( ( (HWND)lParam == GetDlgItem( hDlg, IDC_RADIO1 ) ) || ( (HWND)lParam == GetDlgItem( hDlg, IDC_CHECK1 ) ) ) { RECT r; GetClientRect( hDlg, &r ); DrawThemeParentBackground( (HWND)lParam, (HDC)wParam, &r ); } else { SetTextColor( (HDC)wParam, RGB( 0, 0, 0 ) ); SetBkMode( (HDC)wParam, TRANSPARENT ); } return (INT_PTR)( (HBRUSH)GetStockObject(NULL_BRUSH) );
These are all the necessary steps and information to create a minimal program that demonstrates the problem. Now run the application and notice the differences:
A camera with IDC_RADIO1 and a flag with IDC_CHECK1 will be correctly colored (transparent text with black), while other flags and the switch will not. In addition, after clicking on the tree and click spacebar , you will see a problem with the background of the dialogs.
END OF EDITING
Thanks.
Sincerely.