C++ 使用 GDI+ 绘制文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7299196/
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
Drawing Text with GDI+
提问by Toast
I have searched for some days now to find a possibility to display text on my GDI+ application.
我已经搜索了几天,以找到在我的 GDI+ 应用程序上显示文本的可能性。
I tried using the DrawString()function of GDI+ but the reference on MSDN does not work as it does not match with the parameter list. I am using Visual C++ 2010 Express.
我尝试使用DrawString()GDI+的功能,但 MSDN 上的参考不起作用,因为它与参数列表不匹配。我正在使用 Visual C++ 2010 Express。
I changed the MSDN example to make it compile, like this:
我更改了 MSDN 示例以使其编译,如下所示:
LinearGradientBrush* myBrush = new LinearGradientBrush(Rect(0,0,width,height),Color::Red, Color::Yellow, LinearGradientMode::LinearGradientModeHorizontal);
Font* myFont = new Font(hdc);
RectF rect = RectF(10,10,100,100);
graphics.DrawString(TEXT("Look at this text!"),100, myFont,rect,&StringFormat(0,0), myBrush);
I also tried two other functions:
我还尝试了另外两个功能:
TextOut(hdc,10,10,TEXT("Text"),6);
DrawText(hdc,TEXT("Text"),0,LPRECT(0),0);
None of them shows a text on the screen. Drawing lines, ellipses, etc. works with no problems.
它们都没有在屏幕上显示文本。绘制线条、椭圆等没有问题。
Why doesn't the above text-drawing routine work? Can anybody provide a working example?
为什么上面的文字绘制例程不起作用?任何人都可以提供一个工作示例吗?
回答by Hans Passant
You are making the fairly classic mistake of not checking the return value of Graphics::DrawString(), it will tell you what you did wrong. InvalidParameter is pretty likely here. It is also quite unclear in which context this code runs, that better be inside the WM_PAINT message handler or you'll never see the output. There is also no evidence of cleanup code, as given the code leaks objects badly.
你犯了一个相当经典的错误,即不检查 Graphics::DrawString() 的返回值,它会告诉你你做错了什么。InvalidParameter 很可能在这里。这段代码在哪个上下文中运行也很不清楚,最好在 WM_PAINT 消息处理程序中,否则你永远看不到输出。也没有清理代码的证据,因为代码严重泄漏了对象。
Let's work from a full example, starting from the boilerplate code generated by the Win32 Project template. I know you've got some of this already working but it could be interesting to others reading this answer. Start by giving the required #includes:
让我们从一个完整的示例开始,从 Win32 项目模板生成的样板代码开始。我知道您已经完成了其中的一些工作,但其他人阅读此答案可能会很有趣。首先提供所需的#includes:
#include <assert.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment (lib, "gdiplus.lib")
Locate the WinMain function, we need to initialize GDI+:
找到WinMain函数,我们需要初始化GDI+:
// TODO: Place code here.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Status st = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
assert(st == Ok);
if (st != Ok) return FALSE;
and at the end of the function after the message loop:
并在消息循环后的函数末尾:
GdiplusShutdown(gdiplusToken);
return (int) msg.wParam;
Now locate the window procedure (WndProc) and make the WM_PAINT case similar to this:
现在找到窗口过程 (WndProc) 并使 WM_PAINT 情况与此类似:
case WM_PAINT: {
hdc = BeginPaint(hWnd, &ps);
Graphics gr(hdc);
Font font(&FontFamily(L"Arial"), 12);
LinearGradientBrush brush(Rect(0,0,100,100), Color::Red, Color::Yellow, LinearGradientModeHorizontal);
Status st = gr.DrawString(L"Look at this text!", -1, &font, PointF(0, 0), &brush);
assert(st == Ok);
EndPaint(hWnd, &ps);
} break;
Which produces this:
产生这个:


Modify this code as you see fit, the asserts will keep you out of trouble.
按照您认为合适的方式修改此代码,断言将使您远离麻烦。
回答by SChepurin
MSDN is your friend (true thing): Drawing a Line- code sample: compile and run and Drawing a String-- replace OnPaint() in previous one.
MSDN 是你的朋友(真实的东西): 画一条线- 代码示例:编译并运行并 绘制一个字符串- 替换上一个中的 OnPaint()。

