The changing of the text color using SetTextColor() has worked for years on
Win95, Win98, WinNT and Win2K systems. But, when running WinXP in "Windows
XP style" the text is always black. Change to "Windows classic style" and
the text is colored.
Changing the background color and label text font work correctly on all
versions Windows including XP.
We have tried various combinations of message handling such as::
In OnChildNotify() detect WM_CTRLCOLORSTATIC
At dialog level, in OnCtlColor() detect CTLCOLOR_STATIC
Still, the text is always black. Is there a technique which works on WinXP?
GH
It's no doubt a theming thing. Like how you can't change the color of a
themed progress bar. The theme defines the colors the control uses and that
is that. The only things I can think of as a work around are to remove
theming from the radio and check controls, or implement an NM_CUSTOMDRAW
handler for them and see if you can work out how to draw the thing using the
underdocumented theme API.
--
Jeff Partch [VC++ MVP]
There is no NM_CUSTOMDRAW message detected in OnChildNotify for RadioButton
or CheckBox.
The documentation for that message does not mention button controls.
However, I was able to use:
SetWindowTheme(m_hWnd, (L""), (L""));
in my CreateWindow function to disable WinXP style on a control.
To make it smarter, I use this call only if the normal and focus colors for
text are not black.
The radio and check graphics are then drawn in WinXP style if text is black
and Classic style if the text is colored.
GH
"Jeff Partch [MVP]" <je...@mvps.org> wrote in message
news:eI0um9Kq...@TK2MSFTNGP11.phx.gbl...
Your way works and it sounds much easier! Good job. But just so you don't
think I'm crazy, themed buttons do send the NM_CUSTOMDRAW notification...
Linking with the UxTheme library is a problem if I try to run on non WinXP
systems.
The exe will not load because of a missing DLL. Obviously the Themes
support.
That includes Win 2000 Server and probably 2003 Server. Portability is
essential.
So, maybe I can pursue the NM_CUSTOMDRAW route.
GH.
"Jeff Partch [MVP]" <je...@mvps.org> wrote in message
news:eSAp6fM...@TK2MSFTNGP11.phx.gbl...
There is the delayload mechanism, or you can use the
LoadLibrary/GetProcAddress thing during execution. I've got this in the
archives, but make no promises about whether it's a good idea or not...
enum
{
CELNM_THEME_STATE_UNKNOWN = -1,
CELNM_THEME_STATE_NONE = 0,
CELNM_THEME_STATE_THEMED = 1
};
static INT CEditLineNumberMargin_IsThemedEdit(CEdit& rEdit)
{
INT nRet = CELNM_THEME_STATE_UNKNOWN;
if (IsWindow(rEdit))
{
HMODULE hMod = (HMODULE)GetClassLongPtr(rEdit, GCLP_HMODULE);
if (hMod)
{
if (hMod == GetModuleHandle(_T("Comctl32.dll")))
nRet = CELNM_THEME_STATE_THEMED;
else if (hMod == GetModuleHandle(_T("User32.dll")))
nRet = CELNM_THEME_STATE_NONE;
}
if (nRet)
{
if ((hMod = GetModuleHandle(_T("uxtheme.dll"))))
{
if (FARPROC pfn = GetProcAddress(hMod, "OpenThemeData"))
{
typedef HANDLE (STDAPICALLTYPE* PFN_OPENTHEMEDATA)(HWND,
LPCWSTR);
if (HANDLE h = ((PFN_OPENTHEMEDATA)pfn)(rEdit, L"Edit"))
{
typedef HRESULT (STDAPICALLTYPE*
PFN_CLOSETHEMEDATA)(HANDLE);
if ((pfn = GetProcAddress(hMod, "CloseThemeData")))
((PFN_CLOSETHEMEDATA)pfn)(h);
nRet = CELNM_THEME_STATE_THEMED;
}
else
nRet = CELNM_THEME_STATE_NONE;
}
}
}
}
return nRet;
}
...way back when I archived a post from a Microsoft guy where he says
that...
> Newsgroups: microsoft.public.win32.programmer.ui
> Sent: Tuesday, July 16, 2002 4:40 PM
> Subject: RE: OpenThemeData fails after repeated
OpenThemeData/CloseThemeData calls
> You should open a theme once per window... open it when the window is
> created and close the handle when the window is destroyed. There is a
limit
> of 64K handles per process. The bug is when this limit is reached,
> OpenThemeData does not return NULL.
>
...but I was never clear about how anyone was supposed to interact with
themes under this restriction. Anyway, you may not need all of the above. It
may be enough in your case that the "BUTTON" wndclass originates from
'Comctl32.dll', and if so call SetWindowTheme on it dynamically.