GDI基本图形
Microsoftwindows 的图形设备接口(Graphiccs Device Interface GDI),使应用程序在视频显示器和打印机上使用图形和格式化文本;
一. 设备环境
1. DC是Windows内部的使用的数据结构,它定义了GDI函数在显示设备特定区域的工作方式,对显示器来说,它代表屏幕上的一块区域。
Hdc = ::BeginPaint(hwnd,&ps);
BeginPaint 函数用于取得窗口客户区无效区域的设备环境句柄。
① 如果想要取得整个窗口的设备环境,可以调用如下函数:
HDC hdc = ::GetWindowDC(hwnd);
::ReleaseDC(hwnd,hdc);
② 如果不是在处理WM_PAINT消息,可以使用GetDC函数取得窗口客户区的设备环境句柄,进而进行绘制操作。
Hdc = ::GetDC(hWnd);
::ReleaseDC(hWnd,Hdc);
与BeginPaint和EndPaint的区别是,利用GetDC传回的句柄可以在整个客户区上,不只是在客户区的无效区域绘图。
当然GetDC并不能使客户区无效的区域变有效。
2. 设备环境里,除了代表区域的位置和大小的信息外,还包含绘制图形所需要的其他属性信息(输出文本的字体,画图使用的画笔,删除背景时使用的刷子,选用的坐标系等等),;
3. Windows不允许直接存取设备环境里成员的值,而是采用API函数
::SetTextColor(hdc,RGB(255,0,0));
::SetBkColor(hdc,RGB(0,0,255));
要想使每次windows对DC的设置都保存下来,要在注册窗口类时,加入CS_OWNDC标志;
Wcex.style= CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
二. Windows的像素点和颜色
1. DC上的图形和文本都是由像素点组成的。内存中,用颜色的取值来表示像素点。色深是存储每个像素的为数,一般为24位色。红绿蓝三原色分别占8位
2. Win32中,同一使用32位整数来表示24位的颜色。只使用低24位;宏GetRValue;GetGValue;GetBValue;分别提取各分量的值。
要设置一个像素点的值:
COLORREF SetPixel(HDC hdc,
Intx;
Inty;
COLORREFcrColor;
);用GetPixel()来取得某个像素点的值;
三. 绘制线条;
1. 画单条直线的LineTo,画多条直线的Polyline,PolylineTo;画贝塞尔曲线的PolyBezier和PolyBezierTo;
2. 以To为结尾的函数都以当前点开始画,并改变当前点的位置。
::GetClientRect(hWnd,&rt);//获取制定窗口客户区的大小。
for(int i =rt.left ;i<= rt.right;i+=50)
{
::MoveToEx(hdc,i,rt.top,NULL);
::LineTo(hdc,i,rt.bottom);
}
3. 多线条:
BOOL Polyline(HDC hdc,CONST POINT*lpPoint,int cPoint);
BOOL PolylineTo(HDC hdc,CONST POINT*lpPoint,int cPoints);
PolylineTo函数是从当前点开始画线,然后再连接lpPoin指向的各点。比Polyline函数多一条线。
//思考:POINT怎么动态分配呢? 符合类型new,malloc
4. 要想改变DC中默认的画笔对象,可以使用windows预定义的画笔对象,有BLACK_PEN,WHITE_PEN,NULL_PEN,也可以创建对象;
默认:
HPENhpen = ::GetStockObject(BLACK_PEN);
//selectObject根据句柄种类自动替换原来对象,并返回原来对象句柄
HPEN oldPen = (HPEN)::SelectObject(hdc,hpen);
自定义:
hpen= ::CreatePen(PS_DASH,3,RGB(255,0,0));
5. 绘制区域:
绘制区域的函数工作的时候以当前画笔绘制边线,以当前画刷填充中间的区域。
常用的有:画矩形的Rectangle,画椭圆的Ellipse;画多边形的Polygon,画弦的Chord等。
hBrush= ::CreateSolidBrush(RGB(0,255,0));
oldBrush = (HBRUSH)::SelectObject(hdc,hBrush);
//::Rectangle(hdc,i-50,j-50,i+50,j+50);
::Ellipse(hdc,i-50,j-50,i+50,j+50);
::SelectObject(hdc,oldBrush);
::DeleteObject(hBrush);
① 使用CreateSolidBrush创建的画刷只有颜色的参数,而使用CreateSolidBrush函数创建的画刷还可以使用带特定风格的线条。
② Windows预定义的一些画刷:BLACK_BRUSH,DKGRAY_BRUSH,GRAY_BRUSH,LTGRAY_BRUSH,
四. 坐标系统:
1. 默认坐标系统是MM_TEXT,即左上角为原点,右为x正方向,下为y正方向。
2. 利用函数SetMapMode(HDC hdc,int fnMapMode);可以改变坐标的影射方式。一共有八种。WM_ISOTROPIC,WM_ANISOTROPIC用户自定义;
::SetMapMode(hdc,MM_ANISOTROPIC);//设置坐标映射方式
::SetWindowExtEx(hdc,500,500,NULL);//设置区域逻辑宽度
::SetViewportExtEx(hdc,i,j,NULL);//z坐标轴的方向和坐标轴范围
::SetViewportOrgEx(hdc,0,0,NULL);//原点
::Ellipse(hdc,0,0,500,500);
3. 2
时钟程序
定时器的使用
1. 调用SetTimer将定时器按上,windows就会每隔指定时间向应用程序窗口发送WM_TIMER消息;wParam表示属于哪一个定时器;
2. 使用定时器的方法有两种:①位定时器关联一个窗口句柄;②为定时器关联一个自定义函数的地址;
case WM_TIMER:
if(wParam == Timer1)
{
hdc= ::GetDC(hWnd);
wsprintf(szText,"记数:%d",nNum++);
::TextOut(hdc,0,0,szText,strlen(szText));
::MessageBeep(MB_OK);
}
break;
case WM_LBUTTONDOWN:
if(bSetTimer)
{
::KillTimer(hWnd,Timer1);
bSetTimer= FALSE;
}
else
{
::SetTimer(hWnd,Timer1,250,NULL);
bSetTimer= TRUE;
}
break;
3. 系统时间;
① 获得系统时间的函数是void GetLocalTime(LPSYSTIME lpSystemTime);
4. 2