windows C++ GDI+ 在透明分层窗口上绘制文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4783781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ GDI+ drawing text on a transparent layered window
提问by BNelsey
(unmanaged C++) I already succeeded drawing PNG files to a transparent layered window that I can drag around the desktop, but now my problem is drawing text on a transparent layered window
(非托管 C++)我已经成功地将 PNG 文件绘制到我可以在桌面上拖动的透明分层窗口,但现在我的问题是在透明分层窗口上绘制文本
Here's my code and my attempt at drawing text in the middle, it's important to note that i'm using the screenDC instead of using the one in WM_PAINT messages
这是我的代码和我在中间绘制文本的尝试,重要的是要注意我使用的是 screenDC 而不是 WM_PAINT 消息中的
[edit] updated code after the comments, now i'm just trying to write text on the bitmap before getting the HBITMAP version which i need to use this time I'm using DrawString because textout() isn't GDI+, I hope DrawString really is GDI+ lol still doesn't work though, wonder what i'm doing wrong
[编辑] 在评论后更新了代码,现在我只是想在获得这次我需要使用的 HBITMAP 版本之前在位图上写文本我正在使用 DrawString 因为 textout() 不是 GDI+,我希望 DrawString真的是 GDI+ lol 仍然不起作用,想知道我做错了什么
void Draw() // draws a frame on the layered window AND moves it based on x and y
{
HDC screenDC( NULL ); // grab screen
HDC sourceDC( CreateCompatibleDC(screenDC) );
POINT pos = {x,y}; // drawing location
POINT sourcePos = {0,0}; // top left of image
SIZE size = {100,100}; // 100x100 image
BLENDFUNCTION blendFunction = {0};
HBITMAP bufferBitmap = {0};
Bitmap* TheBitmap = crnimage; // crnimage was already loaded earlier
// ------------important part goes here, my attempt at drawing text ------------//
Gdiplus::Graphics Gx(TheBitmap);
// Font* myFont = new Font(sourceDC);
Font myFont(L"Arial", 16);
RectF therect;
therect.Height = 20;
therect.Width = 180;
therect.X = 0;
therect.Y = 0;
StringFormat format;
format.SetAlignment(StringAlignmentCenter);
format.GenericDefault();
Gdiplus::SolidBrush GxTextBrush(Gdiplus::Color(255, 255, 0,255));
WCHAR thetext[] = L"Sample Text";
int stats = Gx.DrawString(thetext, -1, &myFont, therect, &format, &GxTextBrush);
if(stats) // DrawString returns nonzero if there is an error
msgbox(stats);
stats = Gx.DrawRectangle(&Pen(Color::Red, 3), therect);
// the rectangle and text both draw fine now
// ------------important part goes here, my attempt at drawing text ------------//
TheBitmap->GetHBITMAP(0, &bufferBitmap);
HBITMAP oldBmpSelInDC;
oldBmpSelInDC = (HBITMAP)SelectObject(sourceDC, bufferBitmap);
// some alpha blending
blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.SourceConstantAlpha = wndalpha;
blendFunction.AlphaFormat = AC_SRC_ALPHA;
COLORREF colorKey( RGB(255,0,255) );
DWORD flags( ULW_ALPHA);
UpdateLayeredWindow(hWnd, screenDC, &pos, & size, sourceDC, &sourcePos,
colorKey, &blendFunction, flags);
// release buffered image from memory
SelectObject(sourceDC, oldBmpSelInDC);
DeleteDC(sourceDC);
DeleteObject(bufferBitmap);
// finally release the screen
ReleaseDC(0, screenDC);
}
I've been trying to write text on my layered window for two days now, but from those attempts I know there are several ways I can go about doing this (unfortunately I have no idea how exactly)
我已经尝试在我的分层窗口上写文本两天了,但是从这些尝试中我知道有几种方法可以做到这一点(不幸的是,我不知道具体如何)
The usual option I see is drawing text on a bitmap, then rendering the bitmap itself
我看到的常用选项是在位图上绘制文本,然后呈现位图本身
- Use Gdi+ to load a bitmap
- Create a Graphics object from the bitmap
- Use DrawString to write text to the bitmap
- Dispose of the Graphics object
- Use the bitmap Save method to save the result to a file
- 使用 Gdi+ 加载位图
- 从位图创建一个 Graphics 对象
- 使用 DrawString 将文本写入位图
- 处理 Graphics 对象
- 使用位图 Save 方法将结果保存到文件中
Apparently one can also make a graphics object from a DC, then draw text on the DC, but again i have no clue as to how to do this
显然,也可以从 DC 制作图形对象,然后在 DC 上绘制文本,但我再次不知道如何执行此操作
采纳答案by Adrian McCarthy
The overall approach looks right, but I think you've got some problems with the DrawString
call. Check out the documentation (especially the sample) on MSDN.
整体方法看起来不错,但我认为您在DrawString
通话中遇到了一些问题。查看MSDN上的文档(尤其是示例)。
Gx.DrawString(thetext, 4, NULL, therect, NULL, NULL)
The third, fifth, and sixth parameters (font, format, and brush) probably need to be specified. The documentation doesn't say that they are optional. Passing NULL
for these is probably causing GDI+ to treat the call as a no-op.
可能需要指定第三、第五和第六个参数(字体、格式和画笔)。文档并没有说它们是可选的。传递NULL
这些可能会导致 GDI+ 将调用视为空操作。
The second parameter should not include the terminating L'\0' in the string. It's probably safest to use -1 if your string is always terminated.
第二个参数不应包含字符串中的终止 L'\0'。如果您的字符串总是终止,则使用 -1 可能是最安全的。