GDI+学习笔记6-统计报表的背景与文字的绘制

1. 给窗体加载背景图片
LoadBitmap图片加载
HBITMAP WINAPI LoadBitmapW(HINSTANCE hInstance,LPCWSTR lpBitmapName);
函数作用是从应用程序工程资源中读取位图数据。
第一个参数是资源文件所在模块的实例句柄
第二个参数是位图在资源中的ID名称
在InitInstance()中加载位图:
hbmpBack = LoadBitmapW(hInstance,MAKEINTRESOURCE(IDB_BACK));
LoadImage图片的加载
LoadImage这个函数可以加载位图、光标、图标多种图像数据
从资源加载:
hbmpBack = (HBITMAP)::LoadImage(hInst,MAKEINTRESOURCE(IDB_BACK),IMAGE_BITMAP,
0,0,LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS);
从文件路径加载:
hbmpBack = (HBITMAP)::LoadImage(NULL,_T(".\\1.bmp"),IMAGE_BITMAP,
0,0,LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_CREATEDIBSECTION);
BitBlt: 将颜色块数据从源DC拷贝到目标DC
BOOL BitBlt(
  HDC hdcDest, // 目标DC的句柄
  int nXDest,  int nYDest,  int nWidth,  int nHeight, // 目标区域
  HDC hdcSrc, // 源DC句柄
  int nXSrc, int nYSrc, // 源区域的左上角
  DWORD dwRop // 操作标识,一般是SRCCOPY
);

绘制位图的步骤:
1). 获取目标DC句柄;
2). 创建与目标DC兼容的临时内存DC;
3). 将位图句柄选入到临时内存DC中;
4). 使用BitBlt函数将临时DC中的位图拷贝到目标DC中;
5). 将位图句柄选出临时内存DC;
6). 销毁临时的内存DC.

示例代码为加载位图为窗口背景:
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
HDC hDCMem = ::CreateCompatibleDC(hdc);
HBITMAP hOldBmp = (HBITMAP)::SelectObject(hDCMem,hbmpBack);
BITMAP bmp;
:GetObject(hbmpBack,sizeof(BITMAP),&bmp);
::BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,hDCMem,0,0,SRCCOPY);
::SelectObject(hDCMem,hOldBmp);
::DeleteDC(hDCMem);
EndPaint(hWnd, &ps);
break;
}

获取客户区的大小:
BOOL WINAPI GetClientRect(HWND hWnd,LPREC lpRect);
第一个参数传入窗口的句柄;
第二个参数插入接受返回值Rect的指针

StretchBlt拉伸函数:(与BitBlt函数类似)
BOOL StretchBlt(
  HDC hdcDest,
  int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
  HDC hdcSrc,
  int nXOriginSrc,
  int nYOriginSrc,
  int nWidthSrc,
  int nHeightSrc,
  DWORD dwRop
);
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
HDC hDCMem = ::CreateCompatibleDC(hdc);
HBITMAP hOldBmp = (HBITMAP)::SelectObject(hDCMem,hbmpBack);
BITMAP bmp;
::GetObject(hbmpBack,sizeof(BITMAP),&bmp);
// 获取客户区大小
RECT rcClient;
::GetClientRect(hWnd,&rcClient);
int nWidth = rcClient.right - rcClient.left;
int nHeight = rcClient.bottom - rcClient.top;
::StretchBlt(hdc,0,0,nWidth,nHeight,hDCMem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
::SelectObject(hDCMem,hOldBmp);
::DeleteDC(hDCMem);
EndPaint(hWnd, &ps);
break;
}

绘制文字:
int DrawText(
  HDC hDC, // DC的句柄
  LPCTSTR lpchText, // 要绘制的文本
  int nCount, // 要绘制的文本长度
  LPRECT lpRect, // 绘制的目标区域
  UINT uFormat // 绘制标志,DT_SINGLELINE DT_BOTTOM DT_CENTER
); 

BOOL TextOut(
  HDC hdc,
  int nXStart,
  int nYStart,
  LPCTSTR lpString,
  int cbString
);
hdc: 绘制文字的DC;
nXStart: 文字要绘制的起点位置的X坐标
nYStart: 文字要绘制的起点位置的Y坐标
lpString: 要绘制的文字的字符串指针
cbString: 要绘制的文字的字符个数。

CreateFontIndirect 创建字体
下面表示一种是在Unicode字符集中使用,另一种是在多字节字符集中使用。
#ifdef UNICODE
#define CreateFontIndirect CreateFontIndirectW
#else
#define CreateFontIndirect CreateFontIndirectA
#endif // !UNICODE

LOGFONTA字体结构体:
typedef struct tagLOGFONT {
  LONG  lfHeight; // 字体高度
  LONG  lfWidth; // 字体宽度
  LONG  lfEscapement; // 每个字符串的底线相对于水平线的角度
  LONG  lfOrientation; // 每个字符的基线相对于页底部的角度
  LONG  lfWeight; // 字体的深浅,取值0~1000,400为正常字体,700为黑体,默认为0
  BYTE  lfItalic; // TRUE or FALSE 是否倾向
  BYTE  lfUnderline; // 是否带下划线
  BYTE  lfStrikeOut; // 是否要加中划线
  BYTE  lfCharSet; // 指定字体所要求的字符集
  BYTE  lfOutPrecision; // 指定所要求的输出精度。输出精度定义了输出字体必须如何紧密匹配所要求的字体的高度,宽度,字符转角,倾斜度和间距
  BYTE  lfClipPrecision;// 指定所需要的剪切精度,剪贴精度定义了如何对落在剪贴区域外部的字符进行剪贴
  BYTE  lfQuality; // 指定字体所要求的输出质量
  BYTE  lfPitchAndFamily; // 指定字体的间距和字体系列
  TCHAR lfFaceName[LF_FACESIZE]; //指定一个NULL为终止符的字符串,指定字体的名字
} LOGFONT;

创建字体,绘制文字示例代码:
// 创建字体
LOGFONT logfont;
memset(&logfont,0,sizeof(LOGFONT));
logfont.lfWidth = 20;
logfont.lfHeight = 40;
logfont.lfCharSet = GB2312_CHARSET;
//对字符串数组赋值
_tcscpy(logfont.lfFaceName,_T("宋体"));
HFONT hFont = CreateFontIndirect(&logfont);
HFONT hOldFont = (HFONT)::SelectObject(hdc,hFont);
wstring str = L"VC知识库网站流量统计报表";
::DrawText(hdc,str.c_str(),(int)str.length(),&rcClient,DT_CENTER|DT_TOP|DT_SINGLELINE);
::SelectObject(hdc,hOldFont);
::DeleteObject(hFont);

注意创建字体后要删除字体,否则会造成内存泄露

设置文字颜色:
COLORREF clrOldText = ::SetTextColor(hdc,RGB(0,0,128));
...
::SetTextColor(hdc,clrOldText);

背景模式:
通过SetBKMode设置DC的背景模式,相对应的GetBKMode是用来获取背景模式。
int SetBKMode(HDC hdc,int mode);
参数mode可以有TRANSPARENT值与OPAQUE值,
返回值是hdc在设置之前的模式

库存字体:
库存字体,可以通过GetStockObject函数获取。
GetStockObject(SYSTEM_FONT)获取默认的系统字体的句柄。在缺省情况下,系统使用该字体绘制菜单,文本。除SYSTEM_FONT外还可以设置如下参数:
OEM_FIXED_FONT:原始设备制造商(OEM)相关固定间距(等宽)的字体
ANSI_FIXED_FONT: 在Windows中为固定间距(等宽)的系统字体。
ANSI_VAR_FONT: 变间距的系统字体
DEVICE_DEFAULT_FONT: 设备相关字体
SYSTEM_FIXED_FONT: 固定间距(等宽)的系统字体,仅提供给兼容16位的Windows版本

DrawText函数与TextOut函数的区别:

 相比两种绘制方式,发现DratText是采用绘制区域跟绘制格式来控制文字位置,而TextOut是直接采用起始位置来控制文字位置。所以在自定义位置绘制时,TextOut更灵活一些,而以布局绘制时,DrawText更适合一些。此外DrawText还可以计算所绘制字符串的面积大小,还可以以省略号代替超出区域的文本。

图形编程:
SetPixel: 设置指定点的颜色
COLORREF SetPixel(HDC hDC,int X,int Y,COLORREF crColor);
hDC: 绘制点的DC
X,Y: 坐标位置
crColor: 设置的颜色
返回值为设置颜色之前,点(x,y)的颜色
SetPixel(hdc,100,200,RGB(255,0,0));
COLORREF GetPixel(HDC hDC,int X,int Y): 获取点的颜色
MoveToEx设置线的绘制起点:
MoveToEx(HDC hDC,int X,int Y,LPPOINT(lpPoint));
参数lpPoint就是返回旧的起点坐标,参数为NULL时,表示不返回旧的起点坐标
LineTo:画线
LineTo(HDC hDC,int X,int Y);
示例绘制一条从(100,200)到(300,400)的直线:
::MoveToEx(hdc,100,200,NULL);
::LineTo(hdc,300,400);
Rectangle: 绘制矩形
Rectangle(HDC hdc,int left,int top,int right,int bottom);
在GDI中绘制空心矩形:
::SelectObject(hdc,GetStockObject(NULL_BRUSH));
Rectangle(hdc,100,200,100+300,200+400);
Ellipse: 绘制椭圆
Ellipse(HDC hdc,int left,int top,int right,int bottom);
示例代码:
SelectObject(hdc,GetStockObject(NULL_BRUSH));
Ellipse(hdc,100,100,300,300);
Pie: 绘制饼
BOOL Pie(
  HDC hdc,
  int nLeftRect,
  int nTopRect,
  int nRightRect,
  int nBottomRect,
  int nXRadial1,
  int nYRadial1,
  int nXRadial2,
  int nYRadial2
);
示例代码:
SelectObject(hdc,GetStockObject(NULL_BRUSH));
Pie(hdc,470,440,690,690,692,550,582,441);


库存画笔的选用:
SelectObject(hdc,GetStockObject(WHITE_PEN));
获取并选进宽度为1,颜色为白色,样式为实线的画笔
SelectObject(hdc,GetStockObject(BLACK_PEN));
获取并选进宽度为1,颜色为黑色,样式为实线的画笔
SelectObject(hdc,GetStockObject(NULL_PEN));
获取并选进空画笔

CreatePen: 创建画笔
HPEN CreatePen(int fnPenStyle,int nWidth,COLORREF crColor);
fnPenStyle:画笔样式
PS_SOLID: 实心笔
PS_DASH:  短线式, 要求width<=1
PS_DOT:  点式笔,
PS_DASHDOT
PS_DASHDOTDOT
PS_NULL, 笔不可见
PS_INSIDEFRAME 实心笔,但笔宽向里扩展
创建、使用和销毁自定义画笔:
{
// 创建自定义画笔
HPEN hPen=CreatePen(PS_SOLID,1,RGB(42,187,203));
// 使用自定义画笔
HPEN hPenOld=(HPEN)SelectObject(hdc,hPen);
MoveToEx(hdc,78,315,NULL);
LineTo(hdc,150,170);
// 销毁自定义画笔
SelectObject(hdc,hPenOld);
DeleteObject(hPen);
}

库存画刷:
SelectObject(hdc,GetStockObject(WHITE_BRUSH));

LTGRAY_BRUSH: 亮灰色画刷
GRAY_BRUSH: 灰色画刷
DKGRAY_BRUSH: 暗灰色画刷
BLACK_BRUSH: 黑色画刷
NULL_BRUSH: 空画刷,透明画刷

CreateSolidBrush: 创建单色画刷
HBRUSH CreateSolidBrush(COLORREF color);
示例:使用蓝色画刷填充指定矩形:
{
// 创建自定义单色画刷
HBRUSH hbr = CreateSolidBrush(RGB(0,0,255));
// 选进自定义单色画刷并备份旧画刷
HBRUSH hBrushOld=(HBRUSH)SelectObject(hdc,hbr);
// 填充指定矩形
Rectangle(hdc,480,170,520,316);
SelectObject(hdc,hBrushOld);
DeleteObject(hbr);
}

CreateHatchBrush: 创建带有阴影图案的画刷
HBRUSH CreateHatchBrush(
  _int fnStyle,
  _COLORREF clrref
);


CreatePatternBrush: 创建画刷
HBRUSH CreatePatternBrush(HBITMAP hbm);

posted @ 2015-09-04 01:06  星空天宇  阅读(139)  评论(0编辑  收藏  举报