admin管理员组文章数量:1122847
I attached a project which shows a problem with DrawText()
not outputting the correct color via SetTextColor()
.
Note that if you don't include the manifest for themes, it works.
So the question is, with theming enabled, how do you set your own color for DrawText()
.
Download the project I threw together from here for the "minimal reproducible sample" (as the x64 version).
The bitmap has "TEXT" added to it but it's not red text (unless themes are disabled), it's the background color.
This is the main routine which was already listed but they wanted a reproducible example, so I provided one, then apparently it's too much, so here's the main routine again from the reproducible project:
void AddTextToBitmap(HBITMAP hbitmap)
{
HICON iconnew=NULL;
// buffer for text
TCHAR textbuffer[32];
textbuffer[_countof(textbuffer)-1]=0;
_tcsncpy(textbuffer, _T("TEST"), _countof(textbuffer)-1);
BITMAP bm;
if (GetObject(hbitmap, sizeof(bm), &bm)==sizeof(bm)) {
// get dc to where the icon will go
HDC hdc=GetDC(NULL);
if (hdc) {
// create a DC to modify our bitmap
HDC hmemdc=CreateCompatibleDC(hdc);
if (hmemdc!=NULL) {
// apply the icon bitmap to the dc we created
HGDIOBJ orgmemdcbitmap=SelectObject(hmemdc, hbitmap);
if (orgmemdcbitmap!=NULL) {
// set our white color
SetTextColor(hmemdc, RGB(255, 0, 0)); // RGB(255, 255, 255));
// make text background transparent when writing text
SetBkMode(hmemdc, TRANSPARENT);
// setup rect of dc area for drawing text
RECT rect;
rect.bottom=bm.bmHeight-1;
rect.right=bm.bmWidth-1;
rect.top=2;
rect.left=2;
// draw the text to bar on our icon
DrawText(hmemdc, textbuffer, -1, &rect, DT_TOP|DT_CENTER);
// release our icon bitmap and put back the original bitmap
SelectObject(hmemdc, orgmemdcbitmap);
}
// delete the dc we created
DeleteDC(hmemdc);
}
// release the dc we acquired
ReleaseDC(NULL, hdc);
}
}
}
Again: If you don't enable visual themes it works (red text), if you do (via manifest) it doesn't (text is background color).
Here's the manifest to enable themes for x64 - input file of project manifest option (see the full download project linked above):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="amd64"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
In the test app, I tried setting SetThemeAppProperties(0);
at the top if InitInstance()
(before creating class/window) but that didn't change anything. It's all dependent on the manifest being used or not. When the manifest is not used, you get the red text, also the 32bit graphic has black background area instead of transparent. I think the text is also actually transparent. This gives me an idea that maybe DrawText()
is drawing with the alpha being transparent (0).
The Answer
Not sure why this can't be answered but the issue is related to enabling themes via the manifest which enables support for alpha channel in 32 bit graphics. When DrawText()
draws, it sets the alpha channel to zero (transparent).
To work around it, you can check for themes enabled and 32bit graphic and use a unique oddball color with DrawText()
then use a separate routine to set the actual color and transparency desired. Here's an example of such routine.
void FixDrawTextColor(HBITMAP hbitmap, COLORREF searchcolor, COLORREF desiredcolor, BYTE desiredalpha)
{
BITMAP bm;
if (GetObject(hbitmap, sizeof(bm), &bm)==sizeof(bm)) {
// scan though bits to check
if (bm.bmBitsPixel==32 && bm.bmBits) {
// look for colors to make opaque
for (int y=0; y<bm.bmHeight; ++y) {
BYTE* ppixel=(BYTE*) bm.bmBits + (bm.bmWidthBytes * y);
for (int x=0; x<bm.bmWidth; x++) {
// check if search color that is transparent
if (ppixel[3]==0 && ppixel[0]==GetBValue(searchcolor) && ppixel[1]==GetGValue(searchcolor) && ppixel[2]==GetRValue(searchcolor)) {
// set new color
ppixel[0]=GetBValue(desiredcolor);
ppixel[1]=GetGValue(desiredcolor);
ppixel[2]=GetRValue(desiredcolor);
ppixel[3]=desiredalpha;
}
ppixel+=4;
}
}
}
}
}
本文标签:
版权声明:本文标题:winapi - Win32 DrawText() ignores text color set on the device context and draws text in background color - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736478732a1944342.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论