您的位置:首页 > 其它

GdiplusFlat(6)绘制文本

2015-08-05 16:43 447 查看

本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:/article/9672525.html

在上几篇中,我们说到了通过GdipCreateFromHDC函数将HDC(设备上下文句柄)装换成GDI+的Graphics对象,讲到了画笔和画刷的使用,并演示了何利用GDI+Flat来画图片。这回我们来研究一下如何使用GDI+Flat来画文字

还是和以前一样,我们必须自己声明GDI+Flat函数,自己定义GDI+Flat的数据结构。自己动手,丰衣足食。~~

对于画图片,其实是GDI+调用的GDI+Flat的这几个函数:GdipSetTextRenderingHint、GdipSetSmoothingMode、GdipCreateFontFamilyFromName、GdipCreateStringFormat、GdipSetStringFormatAlign、GdipCreateFont、GdipDrawString、GdipDeleteFont、GdipDeleteFontFamily、GdipDeleteStringFormat以及需要上上篇中的画刷GdipCreateSolidFill、GdipCreateLineBrush和GdipDeleteBrush。

我们把这两个函数自己声明出来!不用那些GDI+类的东西!只用C和Win32的最基本的数据类型!

typedef struct _RectF{
float x;
float y;
float Width;
float Height;
}RectF;
extern "C" int WINAPI GdipSetTextRenderingHint(int graphics,int mode);
extern "C" int WINAPI GdipSetSmoothingMode(int graphics,int smoothingMode);
extern "C" int WINAPI GdipCreateFontFamilyFromName(WCHAR* name,int* fontCollection,int** fontFamily);
extern "C" int WINAPI GdipCreateStringFormat(int formatAttributes,short language,int** format);
extern "C" int WINAPI GdipSetStringFormatAlign(int* format,int align);
extern "C" int WINAPI GdipCreateFont(int* fontFamily,float emSize, int style, int unit, int** font);
extern "C" int WINAPI GdipDrawString(int graphics,WCHAR* string,int length,int* font,RectF* layoutRect,int* stringFormat,int* brush);
extern "C" int WINAPI GdipDeleteFont(int* font);
extern "C" int WINAPI GdipDeleteStringFormat(int* format);
extern "C" int WINAPI GdipDeleteFontFamily(int* fontFamily);





函数不少,来看看都是干嘛用的:

GdipSetTextRenderingHint:设置Graphics对象的文本渲染模式

参数1:Graphics对象

参数2:文本渲染模式(MSDN:https://msdn.microsoft.com/en-us/library/ms534404(v=vs.85).aspx

{TextRenderingHintSystemDefault=0,TextRenderingHintSingleBitPerPixelGridFit=1,TextRenderingHintSingleBitPerPixel=2,TextRenderingHintAntiAliasGridFit=3,TextRenderingHintAntiAlias=4,TextRenderingHintClearTypeGridFit=5}(0:系统默认;2:最佳性能,但不保证效果;3:抗锯齿,但影响性能)

GdipSetSmoothingMode:设置Graphics对象的渲染质量

参数1:Graphics对象

参数2:平滑模式(MSDN:https://msdn.microsoft.com/en-us/library/ms534173(v=vs.85).aspx

-1:无效,0:系统默认,1:最佳性能,2:最佳质量,3:不处理,4:抗锯齿

GdipCreateFontFamilyFromName:创建一个基于指定的字体系列的FontFamily对象

参数1:字体名称

参数2:置NULL

参数3:指向一个FontFamily对象的指针,用于接收FontFamily对象,FontFamily对象是int*

GdipCreateStringFormat:创建一个基于字符串的格式标志和语言的 StringFormat 对象

参数1:指定的格式标志,一般置NULL。(格式标志见MSDN:https://msdn.microsoft.com/en-us/library/ms534181(v=vs.85).aspx

参数2:指定要使用的语言,默认语言为 LANG_NEUTRAL(0)

参数3:指向一个StringFormat对象的指针,用于接收StringFormat对象,StringFormat对象是int*

GdipSetStringFormatAlign:设置文本对齐方式

参数1:StringFormat对象

参数2:对齐方式(StringAlignmentNear=0,StringAlignmentCenter=1,StringAlignmentFar=2)默认为0即可

GdipCreateFont:创建字体

参数1:FontFamily对象

参数2:字号

参数3:字体样式(FontStyleRegular=0,FontStyleBold=1,FontStyleItalic=2,FontStyleBoldItalic=3,FontStyleUnderline=4,FontStyleStrikeout=8)

从0至3依次为:普通,加粗,倾斜,4为下划线,8为删除线

参数4:单位(0到6分别代表:UnitWorld = 0,UnitDisplay= 1,UnitPixel= 2,UnitPoint= 3,UnitInch= 4,UnitDocument= 5,UnitMillimeter= 6(2为像素) )MSDN:https://msdn.microsoft.com/en-us/library/ms534405(v=vs.85).aspx

参数5:指向一个字体对象的指针,用于接收字体对象,字体对象是int*

GdipDrawString:画文字

参数1:Graphics对象

参数2:Unicode字符,要绘制的文本

参数3:字符数,如果字符串以NULL(\0)结尾可以为-1

参数4:字体(font对象)

参数5:指向一个RectF结构的指针,RectF见上面的定义,(x,y:左上角坐标;Width:宽度;Height:高度)

参数6:StringFormat对象

参数7:画刷对象(见上上篇)

GdipDeleteFont、GdipDeleteStringFormat、GdipDeleteFontFamily:销毁指定Font、StringFormat、FontFamily对象,释放资源

参数:要销毁的Font、StringFormat、FontFamily对象

返回值:以上函数成功返回0,失败返回非0

代码示例:

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg){
case WM_PAINT:
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);

int graphics;
GdipCreateFromHDC(hdc, &graphics);//创建Graphics对象
GdipCreateSolidFill(0x900000FF, &brush);//创建单色画刷
PointF p1; p1 = { 0, 0 };
PointF p2; p2 = { 280, 20 };
GdipCreateLineBrush(&p1, &p2, 0xFFFF0000, 0xB00000FF, 0, &linebrush);//创建线性渐变画刷

GdipSetTextRenderingHint(graphics, 3);//设置Graphics对象的文本渲染模式
int* fontfamily;
GdipSetSmoothingMode(graphics, 4);//设置Graphics对象的渲染质量

GdipCreateFontFamilyFromName(L"宋体", NULL, &fontfamily);//创建一个基于指定的字体系列的FontFamily对象
int* format;
GdipCreateStringFormat(0, 0, &format);//创建一个基于字符串的格式标志和语言的 StringFormat 对象
GdipSetStringFormatAlign(format, 0);//设置文本对齐方式
int* font;
GdipCreateFont(fontfamily, 14, 0, 2, &font);//创建字体
RectF rect; rect = { 20, 20, 280, 20 };
GdipDrawString(graphics, L"I love Win32 and GdiplusFlat", -1, font, &rect, 0, brush);//画文字
rect = { 20, 60, 280, 20 };
GdipDrawString(graphics, L"I love Win32 and GdiplusFlat", -1, font, &rect, 0, linebrush);
GdipDeleteFont(font);//销毁指定Font对象,释放资源
GdipDeleteStringFormat(format);//销毁指定StringFormat对象,释放资源
GdipDeleteFontFamily(fontfamily);//销毁指定FontFamily对象,释放资源

GdipDeleteBrush(brush);//销毁画刷
GdipDeleteBrush(linebrush);//销毁画刷

p1 = { 0, 0 };
p2 = { 400, 120 };
GdipCreateLineBrush(&p1, &p2, RGB(164, 73, 163) | 0xFF000000, RGB(232, 162, 0) | 0xA0000000, 0, &linebrush);//创建线性渐变画刷
GdipCreateFontFamilyFromName(L"华文新魏", NULL, &fontfamily);
GdipCreateStringFormat(0, 0, &format);
GdipSetStringFormatAlign(format, 0);
GdipCreateFont(fontfamily, 30, 0, 2, &font);
rect = { 20, 100, 400, 120 };
GdipDrawString(graphics, L"醉时空欢,是一种态度。忘却烦恼,用最真诚的心写最朴实的代码", -1, font, &rect, 0, linebrush);
GdipDeleteFont(font);
GdipDeleteStringFormat(format);
GdipDeleteFontFamily(fontfamily);

GdipDeleteBrush(linebrush);//销毁画刷
GdipDeleteGraphics(graphics);//销毁Graphics对象

EndPaint(hwnd, &ps);
return 0;//告诉系统,WM_PAINT消息我已经处理了,你那儿凉快哪儿玩去吧。


效果图:



完整代码:

#include "stdafx.h"
#include <gdiplus.h>
#include <gdiplusflat.h>
#pragma comment(lib,"gdiplus.lib")//very important

#include <windows.h>
#include <windowsx.h>
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")

//GDI+Flat
typedef struct _GdiplusStartupInput{
unsigned int GdiplusVersion;
unsigned int DebugEventCallback;
BOOL SuppressBackgroundThread;
BOOL SuppressExternalCodecs;
}GdiplusStartupInput;

extern "C" int WINAPI GdiplusStartup(int* token, GdiplusStartupInput *input, int *output);
extern "C" void WINAPI GdiplusShutdown(int token);
extern "C" int WINAPI GdipCreateFromHDC(HDC hdc, int* graphics);
extern "C" int WINAPI GdipDeleteGraphics(int graphics);
//画笔
extern "C" int WINAPI GdipCreatePen1(unsigned int argb_color, float width, int unit, int** pen);
extern "C" int WINAPI GdipDeletePen(int* pen);
//画矩形 画直线
extern "C" int WINAPI GdipDrawRectangle(int graphics, int* pen, float x, float y, float width, float height);
extern "C" int WINAPI GdipDrawLine(int graphics, int* pen, float x1, float y1, float x2, float y2);
//画刷
typedef struct _PointF{
float x;
float y;
}PointF;
extern "C" int WINAPI GdipCreateSolidFill(unsigned int argb_color, int** brush);
extern "C" int WINAPI GdipCreateLineBrush(PointF* point1, PointF* point2, unsigned int argb_color1, unsigned int argb_color2, int wrapMode, int** lineGradient);
extern "C" int WINAPI GdipDeleteBrush(int* brush);
//画填充矩形
extern "C" int WINAPI GdipFillRectangle(int graphics, int* brush, float x, float y, float width, float height);
//画图片
extern "C" int WINAPI GdipLoadImageFromFile(WCHAR* filename, int** image);
extern "C" int WINAPI GdipLoadImageFromStream(LPSTREAM stream, int** image);
extern "C" int WINAPI GdipGetImageDimension(int* image, float* width, float* height);
extern "C" int WINAPI GdipDrawImageRect(int graphics, int* image, float x, float y, float width, float height);
extern "C" int WINAPI GdipDisposeImage(int* image);
//画文字
typedef struct _RectF{
float x;
float y;
float Width;
float Height;
}RectF;
extern "C" int WINAPI GdipSetTextRenderingHint(int graphics, int mode);
extern "C" int WINAPI GdipSetSmoothingMode(int graphics, int smoothingMode);
extern "C" int WINAPI GdipCreateFontFamilyFromName(WCHAR* name, int* fontCollection, int** fontFamily);
extern "C" int WINAPI GdipCreateStringFormat(int formatAttributes, short language, int** format);
extern "C" int WINAPI GdipSetStringFormatAlign(int* format, int align);
extern "C" int WINAPI GdipCreateFont(int* fontFamily, float emSize, int style, int unit, int** font);
extern "C" int WINAPI GdipDrawString(int graphics, WCHAR* string, int length, int* font, RectF* layoutRect, int* stringFormat, int* brush);
extern "C" int WINAPI GdipDeleteFont(int* font);
extern "C" int WINAPI GdipDeleteStringFormat(int* format);
extern "C" int WINAPI GdipDeleteFontFamily(int* fontFamily);

int token;
int* pen;
int* brush;
int* linebrush;
int* image;

//*************************************************************
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

WNDCLASS wc;
const TCHAR* AppName = TEXT("MyWindowClass1");
HWND hwnd1;

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR    lpCmdLine,
_In_ int       nCmdShow)
{
//GDI+开启
GdiplusStartupInput StartupInput = { 0 };
StartupInput.GdiplusVersion = 1;
if (GdiplusStartup(&token, &StartupInput, NULL))MessageBox(0, TEXT("GdiPlus开启失败"), TEXT("错误"), MB_ICONERROR);

//这里是在构建窗口类结构
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;//窗口回调函数指针
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;//实例句柄
wc.hIcon = LoadIcon(hInstance, TEXT("ICON_1"));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//默认指针
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);//默认背景颜色
wc.lpszMenuName = NULL;
wc.lpszClassName = AppName;//窗口类名

//注册窗口类
if (!RegisterClass(&wc))
{
MessageBox(NULL, TEXT("注册窗口类失败!"), TEXT("错误"), MB_ICONERROR);
return 0;
}

//创建窗口
int style = WS_OVERLAPPEDWINDOW;
hwnd1 = CreateWindowEx(NULL, AppName, TEXT("窗口标题"), style, 50, 50, 500, 500, 0, LoadMenu(hInstance, TEXT("MENU1")), hInstance, 0);
if (hwnd1 == NULL)
{
MessageBox(NULL, TEXT("创建窗口失败!"), TEXT("错误"), MB_ICONERROR);
return 0;
}
//无边框窗口
SetWindowLong(hwnd1, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

//显示、更新窗口
ShowWindow(hwnd1, nCmdShow);
UpdateWindow(hwnd1);

//消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

//GDI+关闭
GdiplusShutdown(token);//可以把这个写在消息循环后面,程序退出就销毁,或者在不需要GDI+时调用,比如GDI+窗口的WM_DESTROY消息里调用
return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg){
case WM_PAINT:
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);

int graphics;
GdipCreateFromHDC(hdc, &graphics);//创建Graphics对象
GdipCreateSolidFill(0x900000FF, &brush);//创建单色画刷
PointF p1; p1 = { 0, 0 };
PointF p2; p2 = { 280, 20 };
GdipCreateLineBrush(&p1, &p2, 0xFFFF0000, 0xB00000FF, 0, &linebrush);//创建线性渐变画刷

GdipSetTextRenderingHint(graphics, 3);//设置Graphics对象的文本渲染模式
int* fontfamily;
GdipSetSmoothingMode(graphics, 4);//设置Graphics对象的渲染质量

GdipCreateFontFamilyFromName(L"宋体", NULL, &fontfamily);//创建一个基于指定的字体系列的FontFamily对象
int* format;
GdipCreateStringFormat(0, 0, &format);//创建一个基于字符串的格式标志和语言的 StringFormat 对象
GdipSetStringFormatAlign(format, 0);//设置文本对齐方式
int* font;
GdipCreateFont(fontfamily, 14, 0, 2, &font);//创建字体
RectF rect; rect = { 20, 20, 280, 20 };
GdipDrawString(graphics, L"I love Win32 and GdiplusFlat", -1, font, &rect, 0, brush);//画文字
rect = { 20, 60, 280, 20 };
GdipDrawString(graphics, L"I love Win32 and GdiplusFlat", -1, font, &rect, 0, linebrush);
GdipDeleteFont(font);//销毁指定Font对象,释放资源
GdipDeleteStringFormat(format);//销毁指定StringFormat对象,释放资源
GdipDeleteFontFamily(fontfamily);//销毁指定FontFamily对象,释放资源

GdipDeleteBrush(brush);//销毁画刷
GdipDeleteBrush(linebrush);//销毁画刷

p1 = { 0, 0 };
p2 = { 400, 120 };
GdipCreateLineBrush(&p1, &p2, RGB(164, 73, 163) | 0xFF000000, RGB(232, 162, 0) | 0xA0000000, 0, &linebrush);//创建线性渐变画刷
GdipCreateFontFamilyFromName(L"华文新魏", NULL, &fontfamily);
GdipCreateStringFormat(0, 0, &format);
GdipSetStringFormatAlign(format, 0);
GdipCreateFont(fontfamily, 30, 0, 2, &font);
rect = { 20, 100, 400, 120 };
GdipDrawString(graphics, L"醉时空欢,是一种态度。忘却烦恼,用最真诚的心写最朴实的代码", -1, font, &rect, 0, linebrush);
GdipDeleteFont(font);
GdipDeleteStringFormat(format);
GdipDeleteFontFamily(fontfamily);

GdipDeleteBrush(linebrush);//销毁画刷

if (0){//这是上几篇的代码,用if0作废
//画图片
float x, y;
GdipLoadImageFromFile(L"D:\\1.png", &image);//创建Image对象
GdipGetImageDimension(image, &x, &y);//计算图片宽度和高度
GdipDrawImageRect(graphics, image, 20, 20, x, y);//画图片
GdipDisposeImage(image);//销毁图片,释放资源
//画笔
GdipCreatePen1(0x60FF2015, 1, 2, &pen);//创建画笔
GdipDrawRectangle(graphics, pen, 20, 20, 120, 120);//画矩形
GdipDrawLine(graphics, pen, 50, 60, 170, 340);//画直线
GdipDeletePen(pen);//销毁画笔
//画刷
GdipCreateSolidFill(0x700000FF, &brush);//创建单色画刷
GdipFillRectangle(graphics, brush, 10, 10, 60, 60);//用单色画刷填充矩形
PointF p1; p1 = { 70, 0 };
PointF p2; p2 = { 170, 0 };
GdipCreateLineBrush(&p1, &p2, 0xFFFF0000, 0x400000FF, 0, &linebrush);//创建线性渐变画刷
GdipFillRectangle(graphics, linebrush, 70, 70, 100, 100);//用线性渐变画刷填充矩形
GdipDeleteBrush(brush);//销毁画刷
GdipDeleteBrush(linebrush);//销毁画刷
}
GdipDeleteGraphics(graphics);//销毁Graphics对象

EndPaint(hwnd, &ps);
return 0;//告诉系统,WM_PAINT消息我已经处理了,你那儿凉快哪儿玩去吧。
case WM_CREATE:
break;
case WM_DESTROY://窗口已经销毁
PostQuitMessage(0);//退出消息循环,结束应用程序
return 0;
break;
case WM_LBUTTONDOWN://鼠标左键按下
//让无边框窗口能够拖动(在窗口客户区拖动)
PostMessage(hwnd, WM_SYSCOMMAND, 61458, 0);
break;
/*case WM_MOUSEMOVE://鼠标移动
int xPos, yPos;
xPos = GET_X_LPARAM(lParam);//鼠标位置X坐标
yPos = GET_Y_LPARAM(lParam);//鼠标位置Y坐标
//不要用LOWORD和HIWORD获取坐标,因为坐标有可能是负的
break;*/
default:
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);//其他消息交给系统处理
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: