Windows的图形设备接口与Windows绘图
|
本次学习目标 理解DC, 映像模式, 坐标系统, 窗口和视口; 学习获取绘图工具(画笔/画刷)的句柄, 设置颜色, 能定义映像模式; 会使用常用的绘图函数. 编写程序: 在屏幕上出现一个圆心沿正弦曲线轨迹移动的实心圆. 1. 理解DC, 映像模式, 坐标系统, 窗口和视口; 编写基本的windows绘图程序,获取DC并绘图,然后改变其映射模式、坐标、窗口和视口原点,观察图像输出的变化,理解DC, 映像模式, 坐标系统, 窗口和视口的工作方式。 程序代码如下: #include<windows.h> #include<stdlib.h> #include<string.h> long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam); BOOL InitWindowsClass(HINSTANCE hInstance); BOOL InitWindows(HINSTANCE hInstance,int nCmdShow); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { MSG Message; if(!InitWindowsClass(hInstance)) return FALSE; if(!InitWindows(hInstance,nCmdShow)) return FALSE; while(GetMessage(&Message,0,0,0)) //消息循环 { TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam) { HDC hDC; //定义指向设备上下文的句柄 HPEN hPen; //定义指向画笔的句柄 PAINTSTRUCT PtStr; //定义指向包含绘图信息的结构体变量 switch(iMessage) //处理消息 { case WM_PAINT: //处理绘图消息 hDC=BeginPaint(hWnd,&PtStr); SetMapMode(hDC,MM_ANISOTROPIC); //设置映射模式为MM_ANISOTROPIC hPen=(HPEN)GetStockObject(BLACK_PEN);//设置画笔为系统预定定义的黑色画笔
SelectObject(hDC,hPen); //选择画笔 RoundRect(hDC,50,120,200,-200,15,15); //圆角矩形 Ellipse(hDC,100,50,200,100); //椭圆 EndPaint(hWnd,&PtStr); //结束绘图 return 0; case WM_DESTROY: //结束应用程序 PostQuitMessage(0); return 0; default: //其他消息处理程序 return(DefWindowProc(hWnd,iMessage,wParam,lParam)) ; } } BOOL InitWindows(HINSTANCE hInstance,int nCmdShow) //初始化窗口 { HWND hWnd; hWnd=CreateWindow("WinFill", //生成窗口 "填充示例程序", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if(!hWnd) return FALSE; ShowWindow(hWnd,nCmdShow); //显示窗口 UpdateWindow(hWnd); return TRUE; } BOOL InitWindowsClass(HINSTANCE hInstance) //定义窗口类 { 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=hInstance; WndClass.lpfnWndProc=WndProc; WndClass.lpszClassName="WinFill"; WndClass.lpszMenuName=NULL; WndClass.style=CS_HREDRAW|CS_VREDRAW; return RegisterClass(&WndClass); } 编译并调试程序, 分别改变其映射模式、坐标、窗口和视口原点,观察图像输出的变化 2. 获取绘图工具(画笔/画刷)的句柄, 设置颜色 修改绘图代码为: hPen=(HPEN)GetStockObject(BLACK_PEN);//设置画笔为系统预定定义的黑色画笔 hBrush=(HBRUSH)GetStockObject(DKGRAY_BRUSH); //采用系统预定义的深灰色画刷 SelectObject(hDC,hBrush); //选择画刷 SelectObject(hDC,hPen); //选择画笔 RoundRect(hDC,50,120,200,-200,15,15); //圆角矩形 hBrush=CreateSolidBrush(RGB(220,32,70)); SelectObject(hDC,hBrush); //选择画刷 Ellipse(hDC,100,50,200,100); //椭圆 编译并调试程序 3.在屏幕上绘制一个圆心沿正弦曲线轨迹移动的实心圆 程序源代码如下: #include <windows.h> #include <stdlib.h> #include <string.h> #include <math.h> #define Pi 3.1415926 long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam); //消息处理函数声明. double dfTheta=0,dfRange=100.0; //正弦曲线的角度变量. long i=0,j=0; long lCentreX=0,lCentreY=0,lRadious=(long)(0.5*dfRange); //定义圆心坐标和圆坐标. POINT lpSin[100]; //定义正弦曲线的点坐标. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) //主函数 { MSG Message; //定义消息变量. HWND hWnd; //定义窗口句柄. WNDCLASS WndClass; //定义窗口类. WndClass.cbClsExtra=0; //无窗口类扩展. WndClass.cbWndExtra=0; //无窗口实例扩展. WndClass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH));//背景为白色. WndClass.hCursor=LoadCursor(NULL,IDC_ARROW); //窗口采用箭头光标. WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); //采用缺省图标. WndClass.hInstance=hInstance; //当前应用程序句柄. WndClass.lpfnWndProc=WndProc; //窗口处理函数. WndClass.lpszClassName="SIN"; //窗口类名称. WndClass.lpszMenuName=NULL; //无窗口菜单. WndClass.style=0; //窗口类型为缺省类型. if(!RegisterClass(&WndClass)) //注册窗口. { MessageBeep(0); return FALSE; }
hWnd=CreateWindow("SIN", //窗口类名. "yuan", //标题名. WS_OVERLAPPEDWINDOW, //带标题栏,最大和最小按钮的窗口. CW_USEDEFAULT, //窗口左上角坐标. 0, CW_USEDEFAULT, //采用缺省的宽度和高度. 0, NULL, //无父窗口. NULL, //无主菜单. hInstance, //当前实例句柄. NULL); //不要此参数. ShowWindow(hWnd,nCmdShow); //显示窗口. UpdateWindow(hWnd); //更新并绘制用户区. for(int j=0;j<100;j++) //生成正弦曲线的点坐标. { lpSin[j].x=(long)(j*2*Pi/100*60); lpSin[j].y=(long)(dfRange*sin(j*2*Pi/100)); }
while(GetMessage(&Message,0,0,0)) { TranslateMessage(&Message); //消息循环. DispatchMessage(&Message); } return Message.wParam; } long WINAPI WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam) //消息处理函数. { HDC hDC; //定义设备环境句柄. HBRUSH hBrush; //定义画刷句柄 HPEN hPen; //定义画笔句柄 PAINTSTRUCT PtStr; //定义包含绘图信息的结构体变量 switch(iMessage) { case WM_PAINT: //处理绘图消息. hDC=BeginPaint(hWnd,&PtStr); //获得设备环境指针. SetWindowOrgEx(hDC,-200,-200,NULL); //设置原点坐标为(-200,-200). Polyline(hDC,lpSin,100); //绘制正弦曲线. hPen=(HPEN)GetStockObject(BLACK_PEN);//设置画笔为系统预定定义的黑色画笔 hBrush=(HBRUSH)GetStockObject(DKGRAY_BRUSH); //采用系统预定义的深灰色画刷 SelectObject(hDC,hBrush); //选入画刷. SelectObject(hDC,hPen); //选入画笔. lCentreX=lpSin[i].x; //圆心x坐标. lCentreY=lpSin[i].y; //圆心y坐标. Ellipse(hDC,lCentreX-lRadious,lCentreY-lRadious, lCentreX+lRadious,lCentreY+lRadious); //画圆. i++; if(i>=100) i=0; DeleteObject(hPen); //删除画笔. DeleteObject(hBrush); //删除画刷. EndPaint(hWnd,&PtStr); //删除设备环境指针. Sleep(100); //停0.1秒. if(i<100) InvalidateRect(hWnd,NULL,1); //刷新用户区. return 0; case WM_DESTROY: //关闭窗口. PostQuitMessage(0); return 0; default: return(DefWindowProc(hWnd,iMessage,wParam,lParam)); } } 编译并调试程序, |
|
1.DC, 映像模式, 坐标系统, 窗口和视口程序运行结果: 初始图像:
改变映射模式为MM_LOMETRIC后:
Y向上,X向右,将一个逻辑单位映射为0.1毫米 恢复映射模式为MM_ANISOTROPIC并设置setWindowExtEx(hDC,2,2,0);后:
图形相对于之前缩小 设置SetViewportExtEx(hDC,2,2,0);后
SetViewportExtEx(hDC,2,2,0);与setWindowExtEx(hDC,2,2,0);比例设置的映射比例相同,图像大小与初始一样。 此时图像上面部分不可见,设置SetViewportOrgEx(hDC,300,300,0);将视口原点往右下移动,此时图像输出为:
图像随视口往右下移动,此时可以看见整个图像。 同样再上一步步骤中视口原点不变,改变窗口原点SetWindowOrgEx(hDC,-300,-300,0);此时图像输出与上图相同。 现在,恢复窗口与视口原点并设置SetViewportExtEx(hDC,1,-1,0);此时图像输出为:
图像绕X翻转180°。此时为了能够让图像完全显示,依旧需要将视口原点往下移动即 SetViewportOrgEx(hDC,0,300,0);此时输出如图:
或者移动窗口原点SetWindowOrgEx(hDC,0,300,0);此时输出和上图相同 设置SetWindowExtEx(hDC,1,-1,0);与设置SetViewportExtEx(hDC,1,-1,0)的情况相同。 2. 获取绘图工具(画笔/画刷)的句柄, 设置颜色的运行结果
3.在屏幕上绘制一个圆心沿正弦曲线轨迹移动的实心圆运行结果
|
|
总结: DC, 映像模式, 坐标系统, 窗口和视口; 不同映射模式的逻辑单位映射成的设备单位不同,ANISOTROPIC与ISOTROPIC模式可以通过SetWindowExtEx与SetViewportExtEx函数来确定,其余的为固定尺寸。 不同映射模式的坐标系设定也不同,ANISOTROPIC与ISOTROPIC模式可以通过SetWindowExtEx与SetViewportExtEx函数来确定,其余的有自己固定方向。其中ISOTROPIC模式X轴与Y轴单位比例固定为1:1。 注意在改变视口与窗口原点使图像能够全部显示时,分清窗口在逻辑坐标系中移动的方向和视口在设备坐标系移动的方向!
获取绘图工具(画笔/画刷)的句柄并设置颜色; 可以直接调用函数GetStockObject获取Windows系统提供的8种画刷,也可以调用函数CreateSolidBrush或CreateHatchBrush来创建具有指定颜色的单色画刷或具有指定阴影图案和颜色的画刷。 创建好的画刷记得选入设备环境,不再使用后记得删除。 |
Windows的图形设备接口与Windows绘图的更多相关文章
- 第四章 Windows的图形设备接口及Windows绘图 P83 4-6
实验(实习)名称 图形程序设计及其应用 实验(实习)日期 一.实验目的 1.熟悉图形设备接口的概念及其应用. 二.实验内容及步骤 实验任务 1.熟悉基于图形应用的程序设计: 2.掌握刷新技术及其 ...
- C# Windows Sockets (Winsock) 接口 (转)
在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现.System.Net 命名空间中 ...
- 背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口
[源码下载] 背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口 作者 ...
- 利用FPGA实现PCI总线接口及Windows驱动实现
利用FPGA实现PCI总线接口及Windows驱动实现 关于PCI总线协议,资料网上.书本都是.这里我们仅仅对重点对利用FPGA实现PCI总线接口问题进行简单分析.下图是PCI总线接口信号: 配置空间 ...
- 图形设备接口(GDI)
图形设备接口(GDI,Graphics Device Interface)负责在显示器和打印机上显示图形.GDI 是由几百个函数和一些相关的数据类型.宏和结构构成的.Windows 98/NT 中的图 ...
- C++ GDI图形设备接口
一.概念 1. GDI:(Graphics Device Interfase)图形设备接口,是一个应用程序与输出设备之间的中介. 一方面,GDI向应用程序提供一个与设备无关的编程环境,另一方面,它又以 ...
- OSG图形设备接口GraphicsContext
1.图形设备与相机 在Camera类的成员函数中,setGraphicContext()函数的工作是设置相机对应的图形设备对象,换句话说,下面要介绍的GraphicsContext类就是图形设备对象的 ...
- U盘启动盘的制作--用U盘硬装Windows系统、或是重装Windows系统
借助IT天空的优启通U盘启动盘的制作--用U盘装Windows系统.或是重装Windows系统之U盘启动盘的制作 1.==================================== 2.== ...
- Windows Azure Active Directory (2) Windows Azure AD基础
<Windows Azure Platform 系列文章目录> Windows Azure AD (WAAD)是Windows Azure提供的一个REST风格的服务,为您的云服务提供了身 ...
随机推荐
- Ajax请求的参数
post请求和get请求存放参数位置 post请求和get请求存放参数位置是不同的: post方式参数存放在请求数据包的消息体中. get方式参数存放在请求数据包的请求行的URI字段中,以?开始以pa ...
- 【C++对象模型】使用gcc、clang和VC++显示C++类的内存布局
引言 各种C++实现对C++类/对象的内存布局可能有所不同,包括数据成员的顺序.虚函数表(virtual table: vtbl)的结构.继承关系的处理等.了解C++类/对象的布局,对于理解C++各种 ...
- P2051 中国象棋
P2051 中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中 ...
- .Net Core 使用NLog记录日志到文件和数据库
NLog 记录日志是微软官方推荐使用. 接下来,通过配置日志记录到文件和Sql Server数据库. 第一步:首先添加包NLog.Config (可通过微软添加包命令Install-Package 包 ...
- Linux下的Shell特殊符号大全(转)
在shell中常用的特殊符号罗列如下: # ; ;; . , / \ 'string'| ! $ ${} $? $$ $* "string"* ** ? : ^ $# $@ `co ...
- 【Guava】PreConditions来校验参数
前置条件:让方法调用的前置条件判断更简单. 在我们的日常开发中,经常要对入参进行一定的参数校验,比如是否为空,参数的取值范围是否符合要求等等.这种参数校验如果我们单独进行校验的话,代码的重复率比较高, ...
- Java:对象的强、软、弱和虚引用的区别
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
- h2数据库的简单使用
1.登录H2数据库的WebConsole控制台 2.设置数据库连接 3.连接测试通过之后,点击[连接]按钮,登录到test数据库的webConsole 4.创建表 复制H2数据库提供的样例SQL脚本, ...
- vue测试安装和配置
npm install --save-dev @vue/test-utils mocha mocha-webpack npm install --save-dev jsdom jsdom-global ...
- WPF中Window的ShowInTaskbar、Owner和Topmost属性
1. ShowInTaskbar:设置窗口是否在任务栏上有一席之位,默认为true, 当在父窗口上新开一个子窗口时,任务栏上就会出现两个窗口,所以当要实现 不管开启多少个窗口,在任务栏上都只显示一个窗 ...








