转载自:http://www.cppblog.com/sunshinealike/archive/2009/03/10/76148.html
Windows 图形设备接口( Graphics Device Interface, GDI )是为与设备无关的图形设计的,由操作系统屏蔽了硬件设备的差异,简化了程序员的程序编写工作。
Ÿ 设备上下文( Device Context, DC )
定义了一系列图形对象及其属性的结构,包括图形模式及输出。 PS : DC 一词的翻译上有些疑惑,不明白为什么这么叫。 context: 背景,环境,上下文
目前设备上下文有四种类型:显示,打印,存储和消息类型。
图形对象及其属性:
位图,画刷,调色板,字体,画笔,区域
应用程序每一次图形操作均参照设备 上下文 中的属性执行, DC 可以看作是图形的“输出模板”。
Ÿ 图形刷新
Windows 应用程序在使用过程中,窗口大小的调整,窗口移动或者被其它窗口覆盖后,都必须要刷新原窗口内用户区显示的内容。但是 windows 系统只能在有限的几种情况下自动刷新。因此应用程序必须具有及时处理刷新请求和刷新响应的功能。
Windows 系统通常通过发送 WM_PAINT 消息将刷新请求传递给应用程序。一般情况下,刷新有三种可能:
(1) 窗口移动后的刷新
用户区移动,窗口大小改变,滚动条的使用等
(2) 被覆盖区域的刷新
下拉式菜单关闭后需恢复被覆盖部分,清除消息框后进行的恢复等
(3) 对象穿越后的刷新
光标穿过用户区,图标拖过用户区等
Windows 系统为每个窗口建立了一个 PAINTSTRUCT 结构,该结构中包含了指明一个窗口被另一个窗口覆盖的“无效区域”的最小矩形结构 RECT ,程序可根据这个矩形进行刷新。
常用刷新方法包括:
(1) 保持一个显示输出副本,需要时重绘窗口
(2) 记录发生的事件,需要时重新调用该事件
(3) 重新绘图,简单图形常用的方法
Ÿ 获取设备 上下文
获取设备 上下文 是应用程序输出图形的先决条件,常用函数有:
BeginPaint 响应 WM_PAINT 消息进行图形刷新
GetDC 非 WM_PAINT 消息驱动时用于获取设备 上下文
GetDCEx 返回指向特定窗口客户区的整个窗口句柄,是 GetDC 的扩展
Ÿ 绘图工具与颜色
1. 画笔 & 画刷
画笔的功能是用来画直线和曲线,画刷用于指定区域的填充
可以使用 CreatePen 和 CreateBrush 创建自定义画笔画刷,也或以使用 GetStockObject 函数获取系统默认的样式。
HPEN hPen = CreatePen
(
int nPenStyle,
int nWidth,
COLORREF rgbColor
);
HBRUSH hBrush = CreateBrush
(
int nHatchStyle,
COLORREF rgbColor
)
画笔画刷不再使用时应使用 DeleteObject 函数删除并释放资源
2. 颜色
winodws 使用宏 RGB 定义绘图颜色 RGB(nRed, nGreen, nBlue)
其中 nRed, nGreen, nBlue 分别表示红,绿,蓝的数值。
3. 常用绘图函数
(1) BOOL MoveToEx
{
HDC hdc,
int x, int y,
LPPOINT lpPoint // 存放原画笔位置的 POINT 结构
}
(2) BOOL LineTo
{
HDC hdc,
int x, int y
}
(3) BOOL Rectangle
{
HDC hdc,
int x1, int y1, // 矩形左上角逻辑坐标
int x2, int y2 // 矩形右下角逻辑坐标
}
(4) BOOL Polygon
{
HDC hdc,
LPPOINT lpPoints, // 包含各顶点坐标的 POINT 数组
int nCount // 多边形顶点个数
}
Ÿ 应用实例 – 简单的图形绘制
#include math.h >
const double pi = 3.1415926 ;
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, UINT wParam, LONG lParam)
{
HDC hDC;
HBRUSH hBrh;
HPEN hPen;
POINT oldPt;
PAINTSTRUCT ptStr; // 定义绘图信息结构体
switch (iMsg)
{
case WM_PAINT: // 处理绘图信息
hDC = BeginPaint(hWnd, & ptStr); // 获取设备上下文
SetMapMode(hDC, MM_TEXT); // 设置映射模式
hPen = (HPEN)GetStockObject(BLACK_PEN); // 获取默认黑色画笔
SelectObject(hDC, hPen); // 将画笔选入 设备上下文
hBrh = (HBRUSH)(GetStockObject(DKGRAY_BRUSH)); // 深灰色画刷
SelectObject(hDC, hBrh);
RoundRect(hDC, 50 , 50 , 200 , 350 , 25 , 25 ); // 圆角矩形
hBrh = (HBRUSH)(GetStockObject(HOLLOW_BRUSH)); // 虚画刷,填充无效果
SelectObject(hDC, hBrh);
Pie(hDC, 300 , 50 , 400 , 300 , 300 , 50 , 400 , 50 ); // 饼图
// 一个五角星
MoveToEx(hDC, 500 , 150 , & oldPt);
LineTo(hDC, 650 , 150 );
LineTo(hDC, 525 , 250 );
LineTo(hDC, 575 , 100 );
LineTo(hDC, 625 , 250 );
LineTo(hDC, 500 , 150 );
// 坐标系
MoveToEx(hDC, 700 , 150 , & oldPt);
LineTo(hDC, 700 , 300 );
LineTo(hDC, 1500 , 300 );
MoveToEx(hDC, 700 , 300 , & oldPt);
// 近似的正弦曲线
for ( int i = 0 ; i 3000 ; ++ i)
{
LineTo(hDC, 700 + i * 20 , 300 - sin(i) * 20 );
}
EndPaint(hWnd, & ptStr); // 结束绘图
return 0 ;
case WM_DESTROY:
PostQuitMessage( 0 );
return 0 ;
default : // 其它消息的默认处理函数
return (DefWindowProc(hWnd, iMsg, wParam, lParam));
}
}
// 对窗口进行初始化
BOOL InitWindow(HINSTANCE hInst, int nCmdShow)
{
HWND hWnd;
hWnd = CreateWindow( " WinFill " , // 类名
" 填充示例 " , // 标题
WS_SYSMENU, // 窗口风格
0 , 0 , // 窗口左上角坐标
CW_USEDEFAULT, CW_USEDEFAULT, // 窗口宽高
NULL, NULL,
hInst,
NULL);
if ( ! hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
BOOL InitWindowClass(HINSTANCE hInst)
{
WNDCLASS wndClass;
wndClass.cbClsExtra = 0 ;
wndClass.cbWndExtra = 0 ;
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hIcon = LoadIcon(NULL, " END " );
wndClass.hInstance = hInst;
wndClass.lpfnWndProc = WndProc;
wndClass.lpszClassName = " WinFill " ;
wndClass.lpszMenuName = " NULL " ;
wndClass.style = CS_HREDRAW | CS_VREDRAW;
return RegisterClass( & wndClass);
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
if ( ! InitWindowClass(hInstance))
{
return FALSE;
}
if ( ! InitWindow(hInstance, nCmdShow))
{
return FALSE;
}
while (GetMessage( & msg, 0 , 0 , 0 ))
{
TranslateMessage( & msg);
DispatchMessage( & msg);
}
return msg.wParam;
}