本次学习目标

理解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。

注意在改变视口与窗口原点使图像能够全部显示时,分清窗口在逻辑坐标系中移动的方向和视口在设备坐标系移动的方向!

窗口与视口的映射关系具体可以参考:从窗口到视口的映射.pdf

获取绘图工具(画笔/画刷)的句柄并设置颜色;

可以直接调用函数GetStockObject获取Windows系统提供的8种画刷,也可以调用函数CreateSolidBrush或CreateHatchBrush来创建具有指定颜色的单色画刷或具有指定阴影图案和颜色的画刷。

创建好的画刷记得选入设备环境,不再使用后记得删除。

Windows的图形设备接口与Windows绘图的更多相关文章

  1. 第四章 Windows的图形设备接口及Windows绘图 P83 4-6

    实验(实习)名称  图形程序设计及其应用  实验(实习)日期 一.实验目的 1.熟悉图形设备接口的概念及其应用. 二.实验内容及步骤  实验任务 1.熟悉基于图形应用的程序设计: 2.掌握刷新技术及其 ...

  2. C# Windows Sockets (Winsock) 接口 (转)

    在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现.System.Net 命名空间中 ...

  3. 背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口

    [源码下载] 背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口 作者 ...

  4. 利用FPGA实现PCI总线接口及Windows驱动实现

    利用FPGA实现PCI总线接口及Windows驱动实现 关于PCI总线协议,资料网上.书本都是.这里我们仅仅对重点对利用FPGA实现PCI总线接口问题进行简单分析.下图是PCI总线接口信号: 配置空间 ...

  5. 图形设备接口(GDI)

    图形设备接口(GDI,Graphics Device Interface)负责在显示器和打印机上显示图形.GDI 是由几百个函数和一些相关的数据类型.宏和结构构成的.Windows 98/NT 中的图 ...

  6. C++ GDI图形设备接口

    一.概念 1. GDI:(Graphics Device Interfase)图形设备接口,是一个应用程序与输出设备之间的中介. 一方面,GDI向应用程序提供一个与设备无关的编程环境,另一方面,它又以 ...

  7. OSG图形设备接口GraphicsContext

    1.图形设备与相机 在Camera类的成员函数中,setGraphicContext()函数的工作是设置相机对应的图形设备对象,换句话说,下面要介绍的GraphicsContext类就是图形设备对象的 ...

  8. U盘启动盘的制作--用U盘硬装Windows系统、或是重装Windows系统

    借助IT天空的优启通U盘启动盘的制作--用U盘装Windows系统.或是重装Windows系统之U盘启动盘的制作 1.==================================== 2.== ...

  9. Windows Azure Active Directory (2) Windows Azure AD基础

    <Windows Azure Platform 系列文章目录> Windows Azure AD (WAAD)是Windows Azure提供的一个REST风格的服务,为您的云服务提供了身 ...

随机推荐

  1. java的string和==和equals和hashcode简单理解

    String s1= "abc"; s1是引用变量,在栈里面,如果java的String常量池中没有abc,则开拓一块区域存abc,s1指向常量池中的abc: String s2= ...

  2. 我从Linux走来,选择了Windows

    我从Linux走来,选择了Windows 几天前就想提笔写下这篇,理解很多人一定会对言论不苟同. 但是我相信您看完一个一年多的Linux用户写完的以后,一定也不会太反对 一.为什么我成为一名 Linu ...

  3. 第四天,同步和异常数据存储到mysql,item loader方法

    github对应代码:伯乐在线文章爬取     一. 普通插入方法 1. 连接到我的阿里云,用户名是test1,然后在navicat中新建数据库

  4. leetcode-54-螺旋矩阵

    题目描述: 给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素. 示例 1: 输入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7 ...

  5. leetcode-31-下一个排列

    本题目在凌应标老师的<算法设计与分析>第八次作业中出现,可供参考. 题目描述: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的 ...

  6. 对称矩阵与压缩存储算法(java实现)

    package 数组和矩阵; public class DuiChenJuZhenYaSuo { int[] arr; int order; //矩阵的阶数 int n; //压缩后一位数组的个数 p ...

  7. 40.oracle事务

    一.事务特性 事务必须具备以下四个特性,简称ACID属性 原子性(Atomicity):事务是一个完整的操作.事务的各步操作是不可分割的(原子的):要么都执行,要么都不执行场景:银行转账 A-100 ...

  8. 问题 I: 闪闪发光

    [提交] [状态] [命题人:外部导入] 题目描述 一所位于云南昆明的中医药本科院校--云南中医学院. 因为报考某专业的人数骤减,正面临着停招的危机. 其中有九名少女想到一条妙计——成为偶像, 只要她 ...

  9. 蓝桥杯-学霸的迷宫(BFS+记录操作)

     算法提高 学霸的迷宫   时间限制:1.0s   内存限制:256.0MB      问题描述 学霸抢走了大家的作业,班长为了帮同学们找回作业,决定去找学霸决斗.但学霸为了不要别人打扰,住在一个城堡 ...

  10. postgresql客户端连接错误的解决方法【转】

    今天在重新设置postgresql服务器以后却发现启动不了服务器.错误如下:psql: could not connect to server: No such file or directory   ...