UpdateLayeredWindow后,使用Gdi DrawText文字透明的解决办法
来源:http://stackoverflow.com/questions/5309914/updatelayeredwindow-and-drawtext
要点就是在先在memDc DrawText,然后手动设置DIB的Alpha值,最后通过AlphaBlend贴到DC。
Question:
I'm using UpdateLayeredWindow to display an application window. I have created my own custom buttons and i would like to create my own static text. The problem is that when i try to draw the text on the hdc, the DrawText or TextOut functions overwrite the alpha channel of my picture and the text will become transparent. I tried to find a solution to this but i could not find any. My custom controls are designed in such way that they will do all the drawing in a member function called Draw(HDC hDc), so they can only access the hdc. I would like to keep this design. Can anyone help me? I am using MFC and i would want to achieve the desired result without the use of GDI+.
Answer:
I know this is an old post ... but I just had this very same problem ... and it was driving me CRAZY.
Eventually, I stumbled upon this post by Mike Sutton to the microsoft.public.win32.programmer.gdi newsgroup ... from almost 7 years ago!
Basically, the DrawText (and TextOut) do not play nicely with the alpha channel and UpdateLayeredWindow ... and you need to premultiply the R, G, and B channels with the alpha channel.
In Mike's post, he shows how he creates another DIB (device independent bitmap) upon which he draws the text ... and alpha blends that into the other bitmap.
After doing this, my text looked perfect!
Just in case, the link to the newsgroup post dies ... I am going to include the code here. All credit goes to Mike Sutton (@mikedsutton).
Here is the code that creates the alpha blended bitmap with the text on it:
HBITMAP CreateAlphaTextBitmap(LPCSTR inText, HFONT inFont, COLORREF inColour)
{
int TextLength = (int)strlen(inText);
if (TextLength <= ) return NULL; // Create DC and select font into it
HDC hTextDC = CreateCompatibleDC(NULL);
HFONT hOldFont = (HFONT)SelectObject(hTextDC, inFont);
HBITMAP hMyDIB = NULL; // Get text area
RECT TextArea = {, , , };
DrawText(hTextDC, inText, TextLength, &TextArea, DT_CALCRECT);
if ((TextArea.right > TextArea.left) && (TextArea.bottom > TextArea.top))
{
BITMAPINFOHEADER BMIH;
memset(&BMIH, 0x0, sizeof(BITMAPINFOHEADER));
void *pvBits = NULL; // Specify DIB setup
BMIH.biSize = sizeof(BMIH);
BMIH.biWidth = TextArea.right - TextArea.left;
BMIH.biHeight = TextArea.bottom - TextArea.top;
BMIH.biPlanes = ;
BMIH.biBitCount = ;
BMIH.biCompression = BI_RGB; // Create and select DIB into DC
hMyDIB = CreateDIBSection(hTextDC, (LPBITMAPINFO)&BMIH, , (LPVOID*)&pvBits, NULL, );
HBITMAP hOldBMP = (HBITMAP)SelectObject(hTextDC, hMyDIB);
if (hOldBMP != NULL)
{
// Set up DC properties
SetTextColor(hTextDC, 0x00FFFFFF);
SetBkColor(hTextDC, 0x00000000);
SetBkMode(hTextDC, OPAQUE); // Draw text to buffer
DrawText(hTextDC, inText, TextLength, &TextArea, DT_NOCLIP);
BYTE* DataPtr = (BYTE*)pvBits;
BYTE FillR = GetRValue(inColour);
BYTE FillG = GetGValue(inColour);
BYTE FillB = GetBValue(inColour);
BYTE ThisA;
for (int LoopY = ; LoopY < BMIH.biHeight; LoopY++) {
for (int LoopX = ; LoopX < BMIH.biWidth; LoopX++) {
ThisA = *DataPtr; // Move alpha and pre-multiply with RGB
*DataPtr++ = (FillB * ThisA) >> ;
*DataPtr++ = (FillG * ThisA) >> ;
*DataPtr++ = (FillR * ThisA) >> ;
*DataPtr++ = ThisA; // Set Alpha
}
} // De-select bitmap
SelectObject(hTextDC, hOldBMP);
}
} // De-select font and destroy temp DC
SelectObject(hTextDC, hOldFont);
DeleteDC(hTextDC); // Return DIBSection
return hMyDIB;
}
Here is the code that drives the CreateAlphaTextBitmap method:
{
const char *DemoText = "Hello World!\0";
RECT TextArea = {, , , };
HFONT TempFont = CreateFont(, , , , , , , , , , , , , "Arial\0");
HBITMAP MyBMP = CreateAlphaTextBitmap(DemoText, TempFont, 0xFF);
DeleteObject(TempFont);
if (MyBMP)
{
// Create temporary DC and select new Bitmap into it
HDC hTempDC = CreateCompatibleDC(inDC);
HBITMAP hOldBMP = (HBITMAP)SelectObject(hTempDC, MyBMP);
if (hOldBMP)
{
// Get Bitmap image size
BITMAP BMInf;
GetObject(MyBMP, sizeof(BITMAP), &BMInf);
// Fill blend function and blend new text to window
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = ;
bf.SourceConstantAlpha = 0x80;
bf.AlphaFormat = AC_SRC_ALPHA;
AlphaBlend(inDC, inX, inY, BMInf.bmWidth, BMInf.bmHeight, hTempDC, , , BMInf.bmWidth, BMInf.bmHeight, bf);
// Clean up
SelectObject(hTempDC, hOldBMP);
DeleteObject(MyBMP);
DeleteDC(hTempDC);
}
}
}
还未测试~先放这儿
UpdateLayeredWindow后,使用Gdi DrawText文字透明的解决办法的更多相关文章
- 关于hasNextInt判断后无限循环输出else项的解决办法
话不多说,上来就是干! import java.util.Scanner; public class Test_hasNextInt { /** * @param args */ public sta ...
- WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转)
WCF服务运行一段时间后客户端无法连接WCF服务的解决办法 (转) Windows Communication Foundation (WCF)是Microsoft为构建面向服务的应用提供的分布式通信 ...
- 使用echart的雷达图的时候,如果文字越界的解决办法记录,标签文字自动换行
使用echart的雷达图的时候,如果文字越界的解决办法记录,标签文字自动换行 前几天项目中有一个图表的是用echart生成的,遇到一个问题,就是在手机端显示的售时候,如果文字太长就会超出div,之前的 ...
- windows7开机后,罗技k380无法自动连接解决办法
问题描述: windows7开机后,罗技k380无法自动连接,必须删除设备后重新发现才能正常连接. 解决办法: 是因为笔记本电脑的蓝牙设置问题.按如下设置即可解决. [Bluetooth设置]-[允许 ...
- redhat图形界面启动后出现桌面但是没有登录界面解决办法
redhat图形界面启动后出现桌面但是没有登录界面解决办法 2014年07月11日 10:50:10 阅读数:7931 redhat Linux一直用着好好地,今天打开只有图像界面背景,没有出现登陆界 ...
- 【原】安装Win7和Ubuntu双系统后,Win7耳机无声音的解决办法
最近安装了Ubuntu的桌面版,作成了双系统,可是发现了一个问题:进入Win7后有时插耳机会没有声音,外放有声音.后来更新驱动也没有解决问题,最后在网上查到了解决办法. 产生原因:进入Ubuntu后, ...
- hadoop启动后jps查不到namenode的解决办法
最近由于项目需要开始接触hadoop,在配置伪分布式启动后,jps查询进程发现少了namenode,而DataNode却存在. 下面是我的core-site.xml和hdfs-site.xml配置: ...
- idea 导入项目后 有的项目目录结构不展开解决办法
如图:可能会出现这中国情况. 解决办法: 1.一般项目导入完成后,但是目录不展开, 2.出现这种情况一般情况下, 关闭idea close idea ,然后重新导入一遍就OK.
- PHP网站从Apache转移到Nginx后产生404错误的原因和解决办法
原案例分析: 1.原来的网站在wamp环境下搭建完成,一切正常,上传到虚拟主机环境为lnmp,结果访问时可以打开主页,然后点其他页面全部报404错误: 2.经分析得出原因:原网站环境为wamp使用了伪 ...
随机推荐
- Java 基本数据类型总结一
Java基本数据类型总结一 基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型.它们是我们编程中使用最频繁的类型.java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为变 ...
- JMeter学习笔记(九) 参数化1--函数助手:_CSVRead
1.函数助手:_CSVRead 1)准备数据文件 ,文件可以是.csv格式,.dat格式,txt格式等 2)打开函数助手,生成参数 3)添加HTTP请求,引用参数 4)执行HTTP请求,察看结果树中的 ...
- Python学习1,代码
看了好久的网上视频,今天尝试着写了一串代码: _author_ = "Happyboy" produce_list = [ ('Iphone',5800), ('Mac Pro ...
- day06_08 字符串
1.0 双引号和单引号的区别 a = "Let's go" print(a) #>>>Let's go 2.0 重复输出字符串* print('hello'*2) ...
- android ViewGroup getChildDrawingOrder与 isChildrenDrawingOrderEnabled()
getChildDrawingOrder与 isChildrenDrawingOrderEnabled()是属于ViewGroup的方法. getChildDrawingOrder 用于 返回当前 ...
- PHP7 深入理解
读 PHP7的内核剖析 php7-internal 记录 3 PHP的相关组成 3.1 SAPI php常见的四种运行模式 SAPI:Server Application Programming In ...
- Android社会化分享功能的实现步骤
众所周知,互联网是一个资源共享的地方,在网络上,我们可以分享我们所有认为好的资源.而随着互联网信息爆发式的增长,我们习惯了一键分享功能,比如:微博分享.微信分享.QQ空间分享.人人网分享等等.由此可见 ...
- 【Luogu】P3288方伯伯运椰子(消圈定理)
题目链接 分数规划题,详见luogu题解 #include<cstdio> #include<cstring> #include<cctype> #include& ...
- BZOJ1196 [HNOI2006]公路修建问题 【二分 + Kruskal】
题目 OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织成立了,旨在建立O ...
- 【BZOJ 5000 OI树】
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 107 Solved: 64[Submit][Status][Discuss] Description ...