(不定期修改信息:)
1.刷新四大原因:窗口移动刷新
被覆盖区域刷新-局部刷新被覆盖区域
对象穿越刷新- 被鼠标,图标穿越用户区刷新
提出请求刷新
2.获取设备环境句柄(HDC)
有2种方式:BeginPaint()和GetDC().
BeginPaint
{
HWND hWnd;//窗口句柄
LPPAINSTRUCT lpPaint;//绘制信息结构体
}
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT
PAINTSTRUCT 绘图结构体名;
使用方式:BeginPaint(需绘图窗口句柄,绘图信息结构体指针);//返回值:HDC ,通过这样获取设备环境句柄,我理解为是得到客户区虚拟图.句柄
PAINTSTRUCT的成员介绍:
hdc 设备环境句柄,和BeginPaint返回值相同。
fErase 非0则擦除背景,0则不擦除背景
rcPaint 系统重新绘画区域
后面3个不用管,系统默认
- EndPaint(窗口句柄,(&设备环境句柄))函数释放设备环境句柄
HDC GetDC(HWND);获取设备窗口句柄
int ReleaseDC(HWND,设备窗口句柄);释放设备窗口句柄
BeinPaint和GetDC的区别:BeinPaint只是重绘无效的窗口才作用(被动),GetDC是随时随地都可用窗口(主动)
*问题:绘制信息谁给的?
3.映像模式设置(用实例说明:窗口和视口之间的联系)
int SetMapMode
{
HDC hdc; //设备环境句柄
int fnMapMode;//设备映像模式
}//这个设置我理解为是给客户区虚拟图设置分辨率…
int GetMapMode
{
HDC hdc;//设备环境句柄
}//得到客户区虚拟图的映像模式.
映像模式 逻辑单位 x轴正向 y轴正向
MM_ANISOTROPIC 任意 任意 任意
MM_ISOTROPIC 任意,但x轴与y轴单位相同 任意 任意
MM_HIENGLISH 0.001英寸 右 上
MM_HIMETRIC 0.01毫米 右 上
MM_LOENGLISH 0.01英寸 右 上
MM_LOMETRIC 0.1毫米 右 上
MM_TEXT(常用) 1像素 右 (下)
MM_TWIPS 1/1440英寸 右 上
设置窗口的原点:
BOOL SetWindowOrgEx{
HDC hdc, //设备环境句柄
int x,
int y, //新坐标原点
LPPOINT lpPoint//原来坐标原点
设置视口的坐标原点:
BOOL SetViewportOrgEx(
HDC hdc,
int x,
int y,//视口新坐标原点
LPPOINT lpPoint//视口原来坐标原点
)
设置窗口尺寸:
BOOL SetWindowExtEx(
HDC hdc,
int nXExtent,//窗口水平尺寸
int nYExtent,//窗口垂直尺寸
LPSIZE lpSize //原窗口尺寸
)
设置视口尺寸:
BOOL SetViewportExtEx(
HDC hdc,
int nXExtent,//视口水平尺寸
int nYExtent,//视口垂直尺寸
LPSIZE lpSize//原视口尺寸
)
(xWindow,yWindow)表示窗口右下角坐标 xWinExt,yWinExt表示窗口水平和垂直尺寸,xWinOrg,yWinOrg表示窗口原点
(xViewport,yViewport)表示视口右下角坐标,xViewExt,yViewExt表示视口水平和垂直尺寸,xViewOrg,yViewOrg表示视口原点
xWindow=(xWinExt/xViewExt)*(xViewport-xViewOrg)+xWinOrg;
yWindow=(yWinExt/yViewExt)*(yViewport-yViewOrg)+yWinOrg;
4.画笔,画刷,位图,映射模式的应用说明和部分代码:
创建画笔和画刷:
得到系统画笔句柄
HGDIOBJ GetStockObject(
int fnObject;
)
系统画笔:BLACK_PEN 黑色画笔 WHITE_PEN白色画笔
创建画笔:
HPEN CreatePen(
int fnPenStyle,//画笔风格
int nWidth,//画笔宽度
COLORREF crColor//画笔颜色
)
GetStockObject还可以产生系统预定义的画刷:
风格:PS_SOLID 实线画笔
PS_DOT 点线画笔
PS_DASH 虚线画笔
PS_DASHDOT 点划线
PS_DASHDOTDOT 点-点-划线(nWidth必须是1)
PS_NULL 不显示线条
HBRUSH CreateSolidBrush(
COLORREF crColor//画刷颜色,取值见下表
)
画刷:
BLACK_BRUSH 黑色画刷 DKGRAY_BRUSH 暗灰色画刷
GRAY_BRUSH 灰色画刷 HOLLOW_BRUSH 空画刷
LTGRAY_BRUSH 亮灰色画刷 NULL_BRUSH 空画刷
WHITE_BRUSH 白色画刷
第二种类型的画刷创建:
HBRUSH CreateHatchBrush)
int fnStyle,//阴影风格,取值如下表
COLORREF clrref //前景色
)
阴影风格:
HS_BDIAGONAL 表示45度向上,从左至右的阴影
HS_CROSS 水平和垂直交叉阴影
HS_DIAGCROSS 45度交叉阴影
HS_FDIAGONAL 45度向下,自左至右阴影
HS_HORIZONTAL 水平阴影
HS_VERTICAL 垂直阴影
画笔和画刷需选入设备环境才可以为设备环境服务:
HGDIOBJ SelectObject(
HDC hdc;//设备环境句柄 表示:指定工具进入的设备环境
HGDIOBJ hgdiobj;//GDI对象,GDI=Graphics Device Interface 图形设备接口
)
BOOL DeleteObject(
HGDIOBJ hObject;//删除的GDI对象
)
5.绘图(实例说明)
BOOL MoveToEx( BOOL LineTo(
HDC hdc, HDC hdc,
int x, //光标移动到(x,y); int nXEnd,//从当前位置画一条线到(nXEnd,nYEnd).
int y, int nYEnd,
LPPOINT lpPoint //原来位置 )
)
画长方形:
BOOL Rectangle(
HDC hdc,
int nLeftRect ,//长方形左上角x轴坐标
int nTopRect,//长方形左上角y轴坐标
int nRightRect,//长方形右下角x轴坐标
int nBottomRect //长方形右下角y轴坐标
)
画圆角矩阵:
BOOL RoundRect(
HDC hdc,
int nLeftRect ,//长方形左上角x轴坐标
int nTopRect,//长方形左上角y轴坐标
int nRightRect,//长方形右下角x轴坐标
int nBottomRect //长方形右下角y轴坐标
int nWidth,//圆角的宽度
int nHeight //圆角的高度
)
画椭圆
BOOL Ellipse(
HDC hdc,
int nLeftRect ,//长方形左上角x轴坐标
int nTopRect,//长方形左上角y轴坐标
int nRightRect,//长方形右下角x轴坐标
int nBottomRect //长方形右下角y轴坐标
)
画饼图:
BOOL Pie(
HDC hdc,
int x1,int y1,//左上角坐标
int x2,int y2,//右下角坐标
int x3,int y3,//饼图起始线的坐标
int x4,int y4//饼图终止线的坐标
)
文字输出:
GetStockObject()可获得系统的默认字体:
字体风格
ANSI_FIXED_FONT 在Windows中为变间距(比例间距)系统字体
DEVICE_DEFAUCT_FONT 在Windows NT中为设备相关字体
DEFAULT_GUI_FONT 用户界面对象默认字体
OEM_FIXED_FONT 原始设备制造商(OEM)相关固定间距(零宽)字体
SYSTEM_FONT 系统字体,在默认情况下,系统使用系统字体绘制菜单
SYSTEM_FIXED_FONT 固定间距(等宽)系统字体
DEFAULT_PALETTE 默认调色板,该调色板由系统调色板中的静态色彩组成
创建字体:
HFONT CreateFont
(
int nHeight,//字体高度
int nWidth,//字体宽度
int nEscapement,//指定移位向量和设备x轴之间的一个角度 (十分之一度为单位),字体框相对于正文行角度
int nOrientation,//指定每个字符的基线和设备x轴之间的角度 (字体相对于字体框的角度)
int fnWeight,//指定字体的权值(0~1000) 400标准体,700粗体,0默认值
DWORD fdwItalic,//字体是否为斜体 0为否 1为是.(下同)
DWORD fdwUnderline,//字体是否存在下划线
DWORD fdwStrikeOut,//字体是否存在删除线
DWORD fdwCharSet,//字体的字符集 =文字在计算机内存的表达方式(编码)
DWORD fdwOutputPrecision,//字体的输出精度
DWORD fdwClipPrecision,//字体的剪裁精度
DWORD fdwQuality,//字体的输出质量
DWORD fdwPitchAndFamily,//指定字体间距和字体族
LPCTSTR lpszFace //字体式样 如:宋体,楷体_2312和Times New Roman 等字体
);
BOOL TextOut(
HDC hdc, //设备环境句柄
int nXStart, //字符串的开始位置x坐标
int nYStart, //字符串的开始位置y坐标
LPCTSTR lpString, //字符串
int cbString //字符串中字符的个数 strlen(String)
);//简单地从指定位置输出字符串
可控制输出文字的格式:
int DrawText(
HDC hdc,//设备环境句柄
LPCTSTR lpString,//字符串
int nCount,//字符串个数
LPRECT lpRect,//矩形结构体指针(输出文字区域)
UINT uFormat //格式
)
文字格式表: 简化说明(具体查网)
DT_BOTTOM 文字贴文字框底部
DT_CALCRECT 根据lpRect区域做出相应的输出
DT_CENTER 水平居中
DT_VCENTER 垂直居中 必须要与DT_SINGLE连用,否则GDI无法计算目的矩形
DT_EDITCONTROL 复制多行编辑控制的正文显示特性,就是显示最后一行
DT_END_ELLIPSIS 超出区域会以省略号标识
DT_EXPANDTABS 扩展制表符,每个制表符的默认字符数是8
DT_EXTERNALLEADING 行的外部标头包含在行的宽度里,一般是不包含的。
DT_HIDEPREFIX 忽略正文中的前缀字符(&) 并且前缀字符后面的字符不会出现下划线,其他前缀字符的调用方式不受影响
DT_INTERNAL 用系统字体来计算正文度量
DT_LEFT 正文左对齐
DT_MODIFYSTRING 修改给定的字符串来匹配显示的正文,标志必须和DT_END_ELLIPSIS或DT_PATH_ELLIPSIS同时使用
DT_NOPREFIX 关闭前缀字符的处理
DT_SINGLELINE 显示正文的同一行,回车和换行符都不能运行
DT_TOP 正文顶端对齐
设置文字颜色的函数:
COLORREF SetTextColor(
HDC hdc,
COLORREF crColor//字体颜色 RGB()
);
设置背景颜色的函数:
COLORREF SetBkColor(
HDC hdc,
COLORREF crColor//背景颜色 RGB
);
获得文字信息(主要是位置),从而定位下一个位置输出相对于这个位置的哪里
BOOL GetTextMetrics(
HDC hdc,
LPTEXTMETRIC lptm//指向 字体信息 结构体指针,TEXTMETRIC 结构体存字体信息
);
适用lptm可获得2个重要的信息,字体高度tmHeight 和 加在两行之间的空间间距tmExternalLeading.
下一行的y坐标为 上一行y坐标+字体高度+两行的空间间距. 每次想知道下一行的y位置就要调用这个GetTextMetrics函数获取字体信息
使用图形设计框架进行位图输出:(MFC用于弄背景图,区别还是挺大的,WIN32设置背景图要用画刷才行,日后再尝试)
获取位图句柄并且获取位图信息存放入BITMAP结构体中,目的是为了获取位图的大小参数
HBITMAP LoadBitmap
(
HINSTANCE hInstance,//当前实例句柄 hWnd
LPCTSTR lpBitmapName //位图资源名称 ID
);
//获取内存环境背景 跟设备环境句柄差不多,类似于之前的设备环境不过是在内存逻辑层的.
HDC CreateCompatibleDC
(
HDC hdc;//设备环境句柄
)
输出图形:
BOOL BitBlt
(
HDC hdcDest,//目标设备环境句柄(设备环境句柄)
int nXDest,int nYDest,//位图左上角坐标
int nWidth,nHeight,//显示位图的区域的高度和宽度
HDC hdcSrc, //原设备环境句柄(内存环境句柄)
int nXSrc,int nYSrc,//原设备位图左上角坐标
DWORD dwRop//操作码,如下图:
)
BLACKNESS 输出黑色位图
DSTINVERT 表示使目标矩形区域颜色取反
MERGECOPY 表示使用与操作符将源矩形区域的颜色与特定模式组合在一起
MERGEPAINT 通过使用或操作符将方向的源矩形区域的颜色与目标矩形区域的颜色合并
NOTSRCCOPY 将源矩形区域颜色取反复制到目标区域
NOTSRCERASE 使用或操作符组合源和目标矩形区域的颜色值,然后将合成的颜色取反
PATCOPY 将特定的模式复制到目标位图上
PATINVERT 通过使用异或操作符将源和目标矩形区域内的颜色合并
SRCAND 通过使用与操作符来将源和目标矩形区域内的颜色合并
SRCCOPY 将源矩形区域直接复制到目标矩形区域
SRCERASE 通过使用与操作符将目标矩形区域颜色取反后与源矩形区域的颜色合并
SRCINVERT 通过使用异或操作符将源和目标矩阵区域的颜色合并 *
SRCPAINT 通过使用布尔型或操作符将源和目标矩形区域的颜色合并
WHITENESS 使用白色进行填充
PATCOPY 将特定的模式复制到目标位图上
获取位图结构 方法:
int GetObject
(
HGDIOBJ hgdiobj,// 对象句柄
int cbBuffer,//复制到缓冲区的字节数
LPVOID lpvObject //接受信息的缓冲区地址
)
使用形式为:GetObject(hBitmap,sizeof(BITMAP),(LPVOID)&tm)
BITMAP tm;(BITMAP结构体存着位图信息,例如宽度 长度 ,BitBlt函数用到).
// MyTest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
char szWindowClass[8]={"空测试"};
char szText[15]={"测试"};
HBITMAP hBitmap;
BITMAP bm;
HDC m_hdc;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
MyRegisterClass(hInstance);//注册窗口
if (!InitInstance (hInstance, nCmdShow)) //窗口初始化 返回0失败 否则成功
{
return FALSE;
}
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//窗口初始化
WNDCLASSEX wcex;//窗口类变量wcex
hBitmap=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP1));
GetObject(hBitmap,sizeof(BITMAP),&bm);
wcex.cbSize = sizeof(WNDCLASSEX); //窗口类大小
wcex.style = CS_HREDRAW | CS_VREDRAW;//风格
wcex.lpfnWndProc = (WNDPROC)WndProc;//消息过程
wcex.cbClsExtra = 0;//窗口类额外空间
wcex.cbWndExtra = 0;//窗口实例额外空间
wcex.hInstance = hInstance;//应用程序当前实例句柄
wcex.hIcon = LoadIcon(hInstance,(LPCTSTR)IDI_ICON1);
wcex.hCursor = LoadCursor(NULL,IDC_WAIT);
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND-1);
wcex.lpszMenuName = (LPCSTR)IDR_MENU1;
wcex.lpszClassName = szWindowClass;//类名 随便定义的
wcex.hIconSm = NULL;//默认为左上角图标
return RegisterClassEx(&wcex);//注册窗口
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)//return false or true,成功返回true.
{
//窗口初始化:先创建窗口,成功后 显示出窗口
HWND hWnd;//用于保存当前窗口句柄
hWnd = CreateWindow(szWindowClass, szText, WS_OVERLAPPEDWINDOW, //创建窗口 并返回窗口句柄保存于hWnd.层叠方式
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);//默认弹出 无父窗口 无菜单 当前程序实例句柄 命令行参数
if (!hWnd)//判断是否创建成功若成功则继续
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)//返回消息处理的结果,与收到的消息有关
{
// int wmId, wmEvent;
/* char line1[]="XX学院是什么?";
char line2[]="可说,学院也是学校?";
char line3[]="不可说学校,否?";
char line4[]="你很棒哦???哦呼呼";
char line5[]="注意这是一个XX学院";*/
// int cy;
PAINTSTRUCT pt;//设备环境结构体 存放设备环境参数
HDC hdc;//设备环境句柄
//HFONT hFont;
// RECT rect;
// HPEN hPen;
// HBRUSH hBrush;
// TEXTMETRIC tm;
char a[30]={"You Are Good"};
switch (message)
{
case WM_CREATE:
hdc=GetDC(hWnd);//获取设备环境句柄,必须用GetDC创建设备环境,
//可理解是保存原信息的窗口设备环境,用BeginPaint创建的话就会造成因缩小窗口图片而丢失位图数据
//不过当窗口拉动到一定大小也会造成溢出现象。。
m_hdc=CreateCompatibleDC(hdc);//通过设备环境获取内存环境句柄
ReleaseDC(hWnd,hdc);//释放动态设备环境句柄
break;
case WM_COMMAND:
break;
case WM_PAINT:
/* 测试画笔 画刷 各种画图 调色
hdc=BeginPaint(hWnd,&pt);
hPen=(HPEN)GetStockObject(BLACK_PEN);
SelectObject(hdc,hPen);
Rectangle(hdc,60,100,100,200);
hBrush=CreateSolidBrush(RGB(0,255,0));
SelectObject(hdc,hBrush);
Ellipse(hdc,300,100,500,300);
hPen=CreatePen(PS_SOLID ,1,RGB(22,255,0));
SelectObject(hdc,hPen);
MoveToEx(hdc,300,100,NULL);
LineTo(hdc,500,300);
DeleteObject(hBrush);
hBrush=CreateHatchBrush(HS_FDIAGONAL ,RGB(80,90,200));
SelectObject(hdc,hBrush);
RoundRect(hdc,20,20,80,80,15,15);
RoundRect(hdc,70,70,100,100,12,13);
DeleteObject(hBrush);
hBrush=(HBRUSH)GetStockObject(BLACK_BRUSH);
SelectObject(hdc,hBrush);
Pie(hdc,150,150,300,360,160,160,250,240);
EndPaint(hWnd,&pt);*/
/* 测试映像模式
hdc=BeginPaint(hWnd,&pt);
SetMapMode(hdc,MM_TEXT);
SetWindowOrgEx(hdc,100,100,NULL);
SetWindowExtEx(hdc,500,300,NULL);
SetViewportOrgEx(hdc,100,100,NULL);
SetViewportExtEx(hdc,500,300,NULL);
hPen=(HPEN)GetStockObject(BLACK_PEN);
SelectObject(hdc,hPen);
hBrush=(HBRUSH)GetStockObject(GRAY_BRUSH);
SelectObject(hdc,hBrush);
Ellipse(hdc,100,100,200,200);
DeleteObject(hBrush);*/
/* 测试文字输出
hdc=BeginPaint(hWnd,&pt);
SetTextColor(hdc,RGB(255,255,0));
TextOut(hdc,100,100,line1,strlen(line1));
SetTextColor(hdc,RGB(100,255,10));
SetBkColor(hdc,RGB(8,100,300));
TextOut(hdc,200,200,line2,strlen(line2));
SetBkColor(hdc,RGB(233,211,20));
GetTextMetrics(hdc,&tm);
cy=200+tm.tmHeight+tm.tmExternalLeading;
TextOut(hdc,200,cy,line3,strlen(line3));
hFont=::CreateFont
(20,
0,0,0,
700,1,1,0,
GB2312_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
"楷体_2312"
);
SelectObject(hdc,hFont);
SetTextColor(hdc,RGB(0,0,0));
SetBkColor(hdc,RGB(255,255,255));
GetTextMetrics(hdc,&tm);
cy=cy+tm.tmHeight+tm.tmExternalLeading;
TextOut(hdc,200,cy,line4,strlen(line4));
DeleteObject(hFont);
GetTextMetrics(hdc,&tm);
cy=cy+tm.tmHeight+tm.tmExternalLeading;
rect.left=200;
rect.top=cy;
rect.right=230;
rect.bottom=cy+1000;
DrawText(hdc,line5,strlen(line5),&rect,DT_CENTER|DT_WORDBREAK|DT_NOCLIP);*/
//RECT rect;
//GetClientRect(hWnd,&rect);
//hdc=::BeginPaint(hWnd,&pt);//获取目标设备环境句柄 经过测试这里用BeginPaint创建目标设备环境还是GetDC创建都一样的。
hdc=GetDC(hWnd);
SelectObject(m_hdc,hBitmap);
BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,m_hdc,0,0,SRCCOPY);
//EndPaint(hWnd,&pt);
ReleaseDC(hWnd,hdc);
break;
case WM_DESTROY:
PostQuitMessage(0);//送一个WM_QUIT消息到消息队列,当线程从消息队列里得到WM_QUIT时,会退出消息循环将控制权返回系统
//返回给系统的值是消息WM_QUIT的wParam参数,而这个wParam参数就是这个nExitCode,称谓应用程序退出代码.
//return 0 的意思??
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);//处理其他命令,我理解为是让下一条消息继续进来,无变化。
}
return 0;
}