文档章节

MFC中的DC、CDC、HDC、句柄、设备上下文的不同意思,适合初学者参考

小青_1989
 小青_1989
发布于 2014/05/30 21:31
字数 8802
阅读 197
收藏 0
  • 请问mfc中的dc、cdc、hdc、句柄、设备上下文究竟是什么意思? 希望能解答详细一点点 谢谢了 
    推荐答案 
    都是什么回答啊 ...
    楼主你没有了解mfc的运行机制就去看他写他所以你先要了解他的机制 已经各个cpp.h都是什么
    下面我就给你说下
     
    在mfc程序中,我们并不经常直接调用windows api,而是从mfc类创建对象并调用属于这些对象的成员函数.也就是说mfc封装了windows api 你说你喜欢c++而mfc换一种说法就是一个用c++写的一个函数库然后你来调用只不过这个类不是你写的
               mfc提供数百个类,最重要的、也是编写任何vc++应用程序都必不可少的两个类cwinapp和cframewnd,这两个类是编写复杂庞大应用程序的基石。
    1>封装特性:构成mfc框架的是mfc类库而mfc类库又是c++的一个类库。这些类封装win32应用程序编程接口,ole(object link embed 对象链接嵌入)特性,odbc和dao数据访问的功能。
    2>继承特性:mfc抽象出了众多类的共同特性,并设计出一些基类作为实现其他类的基础,这些类中最重要的类是cobject类和ccmdtarget类,程序员可以从适当的mfc类中派生出自己的类,实现特定的功能达到编程的目的。
    3>虚拟和消息映射:mfc是以c++为基础,当然支持虚函数,但作为一个编程框架必须要解决的是效率问题:如果mfc仅仅通过虚函数来支持动态约束必然会产生大量的虚函数表这样编程框架过于臃肿而且消耗更多的内存。但是mfc建立了消息映射机制这样降低了内存的使用却大大提高了效率
    消息映射是一个将消息和成员函数相互关联的表,当应用程序的框架窗口接收到一个消息时,mfc将搜索该窗口的消息映射,如果存在一个处理消息的处理程序,那么就调用该处理程序.
    它通过宏来实现消息到成员函数的映射,而且这些函数不必是虚拟的成员函数,这样不需要为消息映射函数生成一个很大的虚拟函数表(v表),节省内存。 
    mfc消息映射机制:
    将消息与消息处理函数联系起来,形成一一对应的机制。
    消息映射宏
    声明: declare_message_map 
    定义:
            begin_message_map 
       on_command
       on_control
       on_message 
           end_message_map
    mfc主要组成部分:类、宏和全局函数。
    类是mfc中最主要的内容。mfc类是以层次结构方式组织起来的。mfc中的类分成两部分,除了一些辅助类,大多数的mfc类是直接或间接从根类cobject派生而来。
    mfc宏主要功能:消息映射、运行时对象类型服务、诊断服务、异常处理。 
    mfc约定:全局函数以“afx”为前缀,全局变量以“afx”为前缀
    mfc类的层次关系
    cobject项目类)>ccmdtarget(消息响应类)>
    {
    cwinthread(线程类)>cwinapp(window应用程序类)
    cdocument(文档类)
    cwnd(窗体类)>[
                  cframewnd(框架类)
                  cview(视图类)
                  ]
    }
     
    cobject类由于mfc中大部分类是从cobject类继承而来的,cobject类描述了几乎所有的mfc类的一些公共特性,cobject类为程序员提供了对象诊断、运行时类型识别和序列化等功能。
    ccmdtarget类由cobject类直接派生而来,它负责将消息发送到能够响应这些消息的对象。它是所有能进行消息映射的mfc类的基类。
    cwinapp类在任何mfc应用程序中有且仅有一个cwinapp派生类的对象,它代表了程序中运行的主线程,也代表了应用程序本身。 cwinapp类取代了winmain()主函数在sdk应用程序中的地位。传统sdk应用程序winmain()函数完成的工作。现在由类cwinapp的initapplication(),initinstance()和run()三个成员函数承担。
    cwnd类由ccmdtarget类直接派生而来,该类及其派生类的实例是一个窗口。cwnd类代表了mfc中最基本的gui对象,它是一个功能最完善、成员函数最多的mfc类。
    cframewnd类是cwnd类的派生类,主要用来掌管一个窗口,它取代了sdk应用程序中窗口函数wndproc()的地位。cframewnd类的对象是一个框架窗口,包括边框、标题栏、菜单、最大化按钮、最小化按钮和一个激活的视图。
    cdocument类在应用程序中作为用户文档类的基类,它代表了用户存储或打开的一个文件。
    cview类是mfc中一个很基本的类,它作为其它mfc视图类和用户视图派生类的基类。
    从api编程到mfc编程的过渡:
    winmain()
    {  初始化wndclass
        注册窗体结构
        创建窗口           >>>>>>>>应用程序类cwinapp
        显示窗口
        消息循环

     
    wndproc()
    { switch(…)            
              >>>>>>>>>框架窗口类cframewnd
    }
     
    mfc object和windows object的对应关系:
    描述                 windows句柄       mfc object 
    窗口                  hwnd                    cwnd 
    设备上下文        hdc                      cdc 
    菜单                   hmenu                cmenu 
    笔                       hpen                   cpen
    刷子                   hbrush              cbrush
    字体                   hfont                 cfont
    位图                    hbitmap            cbitmap
    套接字                socket              csocket
     
    三、手工创建一个mfc应用程序:
    注意:创建mfc程序,要创建一个win32空项目,并要选择项目属性中的”在共享dll文件中使用mfc,然后新建我们的文件
    例子:在”hello.h”头文件中添写如下代码:
    class cmyapp:public cwinapp
    {
    public:
     virtual bool initinstance();//虚函数
    };
    class cmainwindow:public cframewnd
    {
    public:
     cmainwindow();
    protected:
     afx_msg void onpaint();
     declare_message_map();//声明消息映射
    };
    在”hello.cpp”源文件中添写如下代码:
    #include 
    #include “hello.h"
    cmyapp myapp;
    bool cmyapp::initinstance()
    {
     m_pmainwnd = new cmainwindow;
     
         m_pmainwnd>showwindow(m_ncmdshow);
     m_pmainwnd>updatewindow();
     return true;
    }
    begin_message_map(cmainwindow,cframewnd)
     on_wm_paint()
    end_message_map()       //消息映射
    cmainwindow::cmainwindow() //构造函数初始化
    {
        create(null,“我的第一个mfc应用程序”);//创建窗体
    }
    void cmainwindow::onpaint()
    {  cpaintdc dc(this);
     crect rect;
     getclientrect(&rect);
      dc.drawtext("hellomfc",1,&rect, dt_singleline|dt_center|dt_vcenter);
    }
    cwinapp是应用程序类,在mfc应用程序中必须从这个类派生出一个类,该派生类是mfc应用程序的入口
    必须定义这个派生类的对象,并且只能有一个这个对象代表整个应用程序。 
    成员函数:initinstance()
     功能:初始化应用程序实例和窗口实例,
     虚函数cwinapp::initinstance必须在派生类中重写。在initinstance函数中,编写初始化代码,如:
    创建一个窗口
     显示一个窗口
    cframewnd类 
    作用:为应用程序提供一个窗口,同时实现消息处理功能。
    成员函数: create()
    功能:创建窗体,将之赋于cframewnd对象上。
    bool create(窗口类型, 窗口标题,显示风格,显示区域,符窗口句柄,菜单,扩展显示风格,上下文对象)共有8个参数,前两个必须给出,后6个可以默认。
    mfc应用程序的核心就是基于cwinapp类的应用程序对象,cwinapp提供了消息循环来检索消息并将消息调度给应用程序的窗口.我们在编写mfc应用程序时,要包含afxwin.h,
    一个mfc应用程序可以有且仅有一个应用程序对象,对象必须声明为在全局范围内有效(也就是全局对象),以便它在程序开始时即在内存中被实例化
    我们的hello mfc的应用程序类被命名为cmyapp,它在hello.cpp中用如下语句进行了实例化:
    cmyapp myapp;
    cmyapp的类声明在hello.h中代码如下:
    class cmyapp:public cwinapp
    {
    public:
     virtual bool initinstance();
    };
    cmyapp没有声明任何的数据成员,只是重写了一个从cwinapp类中继承来的函数,在应用程序的生存期内initinstance的调用比较早,是在应用程序开始运行以后而窗口创建之前,除非initistance创建一个窗口,否则应用程序是不会有窗口,这正是为什么即使最小的mfc应用程序也必须从cwinapp派生出一个类并重写cwinapp::initistance的原因
    initinstance函数:cwinapp::initinstance是一个虚函数,其默认操作仅包含一条语句:return true;
    initinstance是用来执行程序每次开始时都需要进行的初始化工作最好的地方
    在hello.cpp中,cmyapp的initinstance通过实例化hello的cmainwindow类来创建hello窗口,语句:
    m_pmainwnd = new cmainwindow;
     
    构造了一个cmainwindow对象指针,并将其地址复制到了应用程序对象的m_pmainwnd数据成员中,窗口创建以后,initinstance就会通过cmainwindow指针调用showwindow和updatewindow函数显示它:
     
    m_pmainwnd>showwindow(m_ncmdshow);
     
    m_pmainwnd>updatewindow();
    showwindow和updatewindow是所有窗口对象共用的cwnd成员函数其中包括cframewnd类的对象,cmainwindow就是从cframewnd派生出来的.
    要从mfc程序调用一个常规的windows api函数,需要在函数名称前添加一个全局运算符:: 例如:::updatewindow();
    通过生成窗口对象并调用其create函数,mfc应用程序可以创建一个窗口,在cmyapp::initinstance中,hello创建了一个cmainwindow对象,cmainwindow的构造函数生成在屏幕上看到的窗口:
    create(null,”我的第一个mfc应用程序”);
    cpaintdc dc(this);
    mfc的cpaintdc类是从mfc的cdc类派生的,cdc类封装了windows设备环境,以及包含了绘制到屏幕、打印机和其他设备的几十个成员函数
    在mfc中如何处理消息呢?
    在sdk中我们利用的是消息循环和窗口过程函数对消息进行消息处理.
    在mfc中我们用的是消息映射机制.
    下面是将消息映射添加到一个类中需要做的全部工作.
    1>通过将declare_message_map语句添加到类声明中,声明消息映射.
    2>通过放置标识消息的宏来执行消息映射,相应的类将在对begin_message_map和end_message_map的调用之间处理消息
    3>添加成员函数来处理消息
    1、构造cwinapp派生类的对象
    2、系统调用winmain()
    3、winmain调用initinstance,在该函数中创建cframewnd派生类对象,调用create函数创建窗口、调用showwindow函数显示窗口。
    4、之后内部机制调用run,接受用户的消息,并将消息导向默认的处理函数。当接收到wm_quit消息时,run内部调用exitinstance,退出程序。
    mfc采用消息映射(message map)机制取代c/c++语言中的switchcase结构来处理消息。
    消息映射:在mfc中把消息处理函数和它所要处理的特定的消息连接起来的一种机制。
    它通过宏来实现消息到成员函数的映射,而且这些函数不必是虚拟的成员函数,这样不需要为消息映射函数生成一个很大的虚拟函数表(v表),节省内存。 
    mfc消息映射机制包括一组消息映射宏。一条消息映射宏把一个windows消息和其消息处理函数联结起来。
    mfc应用程序框架提供了消息映射功能。
    在类的实现源文件中用begin_message_map()和end_message_map()宏来定义消息映射。
    在类定义的结尾用declare_message_map()宏来声明使用消息映射。
    hello的cmainwindow类只处理一种消息类型—wm_paint,因此其消息映射的实现如下所示:
    begin_message_map(cmainwindow,cframewnd);
     on_wm_paint()
    end_message_map()
    begin_message_map开始了消息映射,并标识了消息映射所属的类和该类的基类
    end_message_map()结束消息映射.
    on_wm_paint()在begin_message_map和end_message_map()之间,称做消息条目,在mfc为100多种window消息提供了宏.
    afx_msg void onpaint();
    declare_message_map()
    afx_msg 醒目地暗示onpaint是一个消息处理程序,
    declare_message_map()声明消息映射
    mfc把消息主要分为三大类:
    (1)、标准windows消息(wm_xxx)
    使用宏:on_wm_xxx()          特点:有默认的消息处理函数
    (2)、命令消息:(wm_command)
    来自于菜单、工具条、按钮等的消息
    使用宏: on_command(命令按钮标识符id,消息处理函数)
    特点:由用户指定消息处理函数
    3、”notification消息”(通知消息)由控件产生:
    bool    布尔值,取值为true或者false
    bstr     32为字符指针
    byte      8位整数无符号的
    colorref     32位数值代表一个颜色值
    dword    32位整数无符号的
    long     32位整数带符号的
    lpctstr   32位指针,指向一个常字符串
    lpvoid    32位指针,指向一个为指定类型的数据
    mfc特有的数据类型:
    1>position :一个数值,代表数组或者链表中元素的位置,在mfc中常用于数据处理类
    2>lprect:32位指针,指向一个不变的矩形区域结构
     
     
     
     
       这是我针对你的问题整理的一些资料很多我想删减一些但我觉得这些都对你很重要
     
    关于cdc(设备上下文) hdc c/c++ 20080229 22:28:01 阅读79 评论0   字号:大中小 订阅 
     
    可以简单的如此理解:
    dc(device context),就是设备描述表(或者叫做设备环境),就像你作画,需要用到画笔,画刷,颜料等等,这些东西就是作画的环境,属于设备dc的属性所有,想作图就先把作图环境准备一下,这跟我们作画是一样的道理。
     
    cdc和hdc简单使用:
    cdc是设备上下文类;
    hdc是设备上下文句柄;
    //cdc-->hdc与hdc->cdc
    cdc dc;
    hdc hdc;
    hdc=dc.m_hdc;
    dc=cdc::fromhandle(hdc);
    // or  hdc=dc.getsafehdc();
     
    挂一段正规文档(来源msdn):
    设备上下文
    设备上下文是一种包含有关某个设备(如显示器或打印机)的绘制属性信息的 windows 数据结构。所有绘制调用都通过设备上下文对象进行,这些对象封装了用于绘制线条、形状和文本的 windows api。设备上下文允许在 windows 中进行与设备无关的绘制。设备上下文可用于绘制到屏幕、打印机或者图元文件。
    cpaintdc 对象将 windows 的常见固定用语进行封装,调用 beginpaint 函数,然后在设备上下文中绘制,最后调用 endpaint 函数。cpaintdc 构造函数为您调用 beginpaint,析构函数则调用 endpaint。该简化过程将创建 cdc 对象、绘制和销毁 cdc 对象。在框架中,甚至连这个过程的大部分也是自动的。具体说来,框架给 ondraw 函数传递(通过 onpreparedc)准备好的 cpaintdc,您只需绘制到 cpaintdc 中。根据调用 ondraw 函数的返回,cpaintdc 被框架销毁并且将基础设备上下文释放给 windows。
    cclientdc 对象封装对一个只表示窗口工作区的设备上下文的处理。cclientdc 构造函数调用 getdc 函数,析构函数调用 releasedc 函数。cwindowdc 对象封装表示整个窗口(包括其框架)的设备上下文。
    cmetafiledc 对象将绘制封装到 windows 图元文件中。与传递给 ondraw 的 cpaintdc 相反,在这种情况下您必须自己调用 onpreparedc。
    鼠标绘图框架程序中的大多数绘图(由此,大部分设备上下文参与)都在视图的ondraw 成员函数中完成。但是,您仍然可以将设备上下文对象作其他用途使用。例如,若要在视图中提供鼠标运动的跟踪回馈,只需直接绘制到视图中而无需等待调用 ondraw。
    在这种情况中,可以使用 cclientdc 设备上下文对象直接绘制到视图中。
     
    再来一段比较清晰容易理解的。
    一、区别与联系
    hdc是句柄;
    cdc是mfc封装的windows设备相关的一个类;
    cclientdc是cdc的衍生类,产生对应于windows客户区的对象
    hdc是windows的一种数据类型,是设备描述句柄。
    而cdc是mfc里的一个类,它封装了几乎所有的关于hdc的操作。   
    也可以这样说,hdc定义的变量指向一块内存,这块 内存用来描述一个设备的相关的内容,所以也可以认为hdc定义的是一个指针;而cdc类定义一个对象,这个对象拥有hdc定义的一个设备描述表,同时也包含与hdc相关的操作的函数。这与hpen和cpen,point与cpoint之间的差别是一样的。

    二、获得cdc *
    cdc* pdc
    pdc=getdc();//原型cdc* cwnd::getdc() 

    三、获得hdc
    hdc hdc;
    1,hdc=getdc(pcpp>hwnd);
    2,pdc>m_hdc;
    3,(sdk中找不到相关类的支持)
        memdcxp mdcxp;
       getmemdcxp(&mdcxp);
        hdc = mdcxp.hmemdc;
    4,hdc=::getdc(hwnd handle)

    四、转换(?,未确定用法的正确性)
    cdc* pdc
    hdc hdc;
    pdc=attach(hdc);
    hdc=getsafehdc(pdc);
    pdc>m_hdc=hdc;
     
    下面一段翻译自msdn sdk文档
        cdc类定义的是设备上下文对象的类。cdc对象提供处理显示器或打印机等设备上下文的成员函数,以及处理与窗口客户区对应的显示上下文的成员。    
       通过cdc对象的成员函数进行所有的绘图。类对设备上下文操作提供了成员函数,处理绘图工具。安全型图形设备接口(gdi)对象收集,以及处理颜色和调色板。它还为获取和设置绘图属性、映射,处理视点、窗口扩展、转换坐标,处理区域、剪贴、绘制直线及绘制简单椭圆和多边形等形状提供了成员函数。另外还为绘制文本、处理字体,使用打印机跳转,滚动和播放元文件提供成员函数。    
       使用cdc对象时要构造它,然后调用与它平等的、使用设备上下文的windows函数的成员函数。    
      为了特定用途,microsoft基本类库提供了几个cdc派生类。cpaintdc包括beginpaint和endpaint调用。cclientdc管理窗口用户区对应的显示上下文。cwindowdc管理与整个窗口对应的显示上下文,包括它的结构和控件。cmetafiledc与带元文件的设备上下文对应。    
       cdc包含m_hdc和m_hattribdc两个设备上下文,它们在cdc对象创建时参考同一个设备。cdc指导所有对m_hdc的输出gdi调用以及对m_hattribdc的大部分属性gdi调用(gettextcolor是属性调用的例子,而settextcolor是一个输出调用)。    
       例如框架使用这两个设备上下文实现cmetafiledc对象,在从物理设备读取属性期间向元文件发送输出。打印预览以相同风格在框架中实现。还可以以相似方法在特殊应用代码中使用这两个设备上下文。    
     
    http://zoudaokou2006.blog.163.com/blog/static/66650867200812910281360/
    cdc、hdc、pdc (zz)mfc 20091202 22:44:01 阅读275 评论0   字号:大中小 订阅 
    1.cdc *pdc和hdc hdc有什么不同,类似的有cwnd *pwnd和hwnd?

    pdc是类指针
    hdc是windows句柄
    通过pdc获得hdc:
    hdc hdc=pdc>getsafehdc();
    通过hdc获得pdc:
    cdc *pdc=new cdc;
    pdc>attach(hdc);

    2.hdc和cdc有本质区别

    hdc是windows的一种数据类型,是设备描述句柄。而cdc是mfc里的一个类,它封装了几乎所有的关于hdc的操作。也可以这样说,hdc定义的变量指向一块内存,这内存用来描述一个设备的相关的内容,所以也可以认为hdc定义的是一个指针;而cdc类定义一个对象,这个对象拥有hdc定义的一个设备描述表,同时也包含与hdc相关的操作的函数。这与hpen和cpen,point与cpoint之间的差别是一样的。

    cdc是对hdc的相关操作进行封装,例如cdc的一个textout函数隐去其错误检测,完全可以简化到这样程度cdc:textout( int x, int y, const cstring& str )
    {
        textout( m_hdc, x, y, (lpctstr)str, str.getlength() );
    }

    m_hdc就是cdc的成员变量hdc m_hdc;
    cdc有一个operatorhdc() const { return m_hdc; }   
    你可以把它当成一个hdc使用

    3.this是dc输出目标窗口的指针,通过它可以得到窗口句柄,对象带参构造这有什么奇怪的呢?   
        
        cpaintdc        无效区dc,相当于beginpaint,    endpaint  
        cclientdc       客户区dc,相当于getdc,        releasedc   
        cwindowdc       整窗口dc, 相当于getwindowdc,   releasedc   
        cdc            任何dc,  相当于createdc,      deletedc
    hdc,cdc,cclientdc的区别和联系是什么?图片处理代码 20100221 16:32:57 阅读152 评论0   字号:大中小 订阅 
    简而言之,hdc是句柄;cdc是mfc封装的windows 设备相关的一个类;cclientdc是cdc的衍生类,产生对应于windows客户区的对象 
    pdc 是 类指针 
    hdc 是windows句柄 
    通过pdc获得hdc: 
    hdc hdc=pdc>getsafehdc(); 
    通过hdc获得pdc: 
    cdc *pdc=new cdc; 
    pdc>attach(hdc);

    hdc是windows的一种数据类型,是设备描述句柄。 
    而cdc是mfc里的一个类,它封装了几乎所有的关于 
    hdc的操作。 
    也可以这样说,hdc定义的变量指向一块内存,这块 
    内存用来描述一个设备的相关的内容,所以也可以 
    认为hdc定义的是一个指针;而cdc类定义一个对象, 
    这个对象拥有hdc定义的一个设备描述表,同时也包 
    含与hdc相关的操作的函数。 
    这与hpen和cpen,point与cpoint之间的差别是一样 

    显然   
      cdc是类   
      hdc是句柄   
      cdc是包了hdc的类
    cdc和hdc的区别与转换程序设计 20090728 21:46:10 阅读46 评论0   字号:大中小 订阅 
    源自: http://www.thatsky.cn/article.asp?id=81
    一、区别与联系
    hdc是句柄;cdc是mfc封装的windows  设备相关的一个类;cclientdc是cdc的衍生类,产生对应于windows客户区的对象
    hdc是windows的一种数据类型,是设备描述句柄。
    而cdc是mfc里的一个类,它封装了几乎所有的关于hdc的操作。   
    也可以这样说,hdc定义的变量指向一块内存,这块 内存用来描述一个设备的相关的内容,所以也可以   认为hdc定义的是一个指针;而cdc类定义一个对象,   这个对象拥有hdc定义的一个设备描述表,同时也包   含与hdc相关的操作的函数。   
    这与hpen和cpen,point与cpoint之间的差别是一样的。

    二、获得cdc *
    cdc* pdc
    pdc=getdc();

    三、获得hdc
    hdc hdc;
    1,hdc=getdc(pcxp>hwnd);
    2,pdc>m_hdc;
    3,
    memdcxp mdcxp;
    getmemdcxp(&mdcxp);
    hdc = mdcxp.hmemdc;
    4,hdc=::getdc(hwnd handle)

    四、转换
    cdc* pdc
    hdc hdc;
    pdc=attach(hdc);
    hdc=getsafehdc(pdc);
    pdc>m_hdc==hdc
     
    设备描述表
    设备描述表  dc(device context)设备描述表 
      设备描述表是一个定义一组图形对象及其属性、影响输出的图形方式(数据)结构。windows提供设备描述表,用于应用程序和物理设备之间进行交互,从而提供了应用程序设计的平台无关性。设备描述表又称为设备上下文,或者设备环境。 
      设备描述表是一种数据结构,它包括了一个设备(如显示器和打印机)的绘制属性相关的信息。所有的绘制操作通过设备描述表进行。设备描述表与大多 win32结构不同,应用程序不能直接访问设备描述表,只能由各种相关api函数通过设备描述表的句柄间接访问该结构。 
      设备描述表总是与某种系统硬件设备相关。比如屏幕设备描述表与显示设备相关,打印机设备描述表与打印设备相关等等。 
      屏幕设备描述表,一般我们简单地称其为设备描述表。它与显示设备具有一定的对应关系,在windows gdi界面下,它总是相关与某个窗口或这窗口上的某个显示区域。通常意义上窗口的设备描述表,一般指的是窗口的客户区,不包括标题栏、菜单栏所占有的区域,而对于整个窗口来说,其设备描述表严格意义上来讲应该称为窗口设备描述表,它包含窗口的全部显示区域。二者的操作方法完全一致,所不同的仅仅是可操作的范围不同而已。 
      windows 窗口一旦创建,它就自动地产生了与之相对应的设备描述表数据结构,用户可运用该结构,实现对窗口显示区域的gdi操作,如划线、写文本、绘制位图、填充等,并且所有这些操作均要通过设备描述表句柄了进行。
     
    如何理解设备描述表???开发 20081127 11:02:35 阅读29 评论0   字号:大中小 订阅 
    设备描述表是一个定义一组图形对象及其属性、影响输出的图形方式(数据)结构。windows提供设备描述表,用于应用程序和物理设备之间进行交互,从而提供了应用程序设计的平台无关性。设备描述表又称为设备上下文,或者设备环境。     
        设备描述表是一种数据结构,它包括了一个设备(如显示器和打印机)的绘制属性相关的信息。所有的绘制操作通过设备描述表进行。设备描述表与大多win32结构不同,应用程序不能直接访问设备描述表,只能由各种相关api函数通过设备描述表的句柄间接访问该结构。   
        设备描述表总是与某种系统硬件设备相关。比如屏幕设备描述表与显示设备相关,打印机设备描述表与打印设备相关等等。   
        屏幕设备描述表,一般我们简单地称其为设备描述表。它与显示设备具有一定的对应关系,在windows   gdi界面下,它总是相关与某个窗口或这窗口上的某个显示区域。通常意义上窗口的设备描述表,一般指的是窗口的客户区,不包括标题栏、菜单栏所占有的区域,而对于整个窗口来说,其设备描述表严格意义上来讲应该称为窗口设备描述表,它包含窗口的全部显示区域。二者的操作方法完全一致,所不同的仅仅是可操作的范围不同而已。   
        windows  窗口一旦创建,它就自动地产生了与之相对应的设备描述表数据结构,用户可运用该结构,实现对窗口显示区域的gdi操作,如划线、写文本、绘制位图、填充等,并且所有这些操作均要通过设备描述表句柄了进行。   
     /***************************************************************************************/  
      书中是这么说的,但是如何理解啊?   
      如果将设备描述表理解成为设备的一种抽象地描述(或者说是硬件在数据结构上一种映射),那么显示设备描述表对应显示器,在编写程序的时候现在假设以getdc获得设备描述标的句柄。   
      hdc   =   getdc(hwnd);//获得窗口设备描述表句柄   
      [使用gdi函数]  
      releasedc(hwnd,   hdc);   
      我想知道这个过程和显存的关系。也就是如何通过显存绘制到显示器对应的窗口上的。   
      再确切地说就是gdi绘制既然针对的是设备描述表,那么设备描述表是否在内存中?   
      他和显存之间的关系是什么?
    通过设备描述表调用显示卡驱动,由显示卡驱动程序访问显存实现绘图输出,因此在gdi下面是无法直接访问到显存的。这种方式主要是提供了统一的编程界面,使得编程人员不用考虑具体的设备的特性,一切和设备打交道的工作交由系统完成,编程者只要调用统一的gdi函数即可。设备描述表在内存中是存在的。
                                                                                                                                                    转自csdn
    gdi是graphics device interface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有windows程序的图形输出。
      在windows操作系统下,绝大多数具备图形界面的应用程序都离不开gdi,我们利用gdi所提供的众多函数就可以方便的在屏幕、打印机及其它输出设备上输出图形,文本等操作。gdi的出现使程序员无需要关心硬件设备及设备驱动,就可以将应用程序的输出转化为硬件设备上的输出,实现了程序开发者与硬件设备的隔离,大大方便了开发工作。 
      gdi是如何实现输出的? 
      要想在屏幕或者其它输出设备上输出图形或者文字,那么我们就必须先获得一个称为设备描述表( dc:device context)的对象的句柄,以它为参数,调用各种gdi函数实现各种文字或图形的输出。设备描述表是gdi内部保存数据的一种数据结构,此结构中的属性内容与特定的输出设备(显示器,打印机等)相关,属性定义了gdi函数的工作细节,在这里属性确定了文字的颜色,x坐标和y坐标映射到窗口显示区域的方式等。
      设备描述表句柄一旦获得,那么系统将使用默认的属性值填充设备描述表结构。
      如果有必要,我们可以使用一些gdi函数获取和改变设备描述表中的属性值。
    如何使用设备描述表20070222 19:46:18 www.hackbase.com  来源:互联网
    本文示例源代码下载
     
      windows 程序在屏幕、打印机或其它设备上画图时,它并不是将像素直接输出到设备上,而是将图绘制到由设备描述表表示的
     
    本文示例源代码下载
     
      windows 程序在屏幕、打印机或其它设备上画图时,它并不是将像素直接输出到设备上,而是将图绘制到由设备描述表表示的逻辑意义上的"显示平面"上去。设备描述表(dc)是windows中的一种数据结构,它包含gdi需要的所有关于显示界面情况的描述字段,包括相连的物理设备和各种各样的状态信息。在windows画图之前,windows程序从gdi获取设备描述表句柄(hdc),并在每次调用完gdi输出函数后将句柄返回给gdi。本文将对如何获得和释放hdc以及cdc及其派生类的使用方法进行演示说明。
     
      下载示例工程 dcdemo 具体说明:
     
      1、按钮idc_getdc_apinull的函数
     
    voidcdcdemodlg::ongetdcapinull()
    {
      hdchdc=::getdc(null);
      ::movetoex(hdc,0,0,null);
      lineto(hdc,200,20);
      ::releasedc(null,hdc);
    }  该段代码具体演示了如何使用api函数getdc(null),取得屏幕的hdc.并进行画图。 hdcgetdc(hwnd hwnd); //功能:取得hwnd窗口的设备描述表句柄。当hwnd参数为null时,取得整个屏幕的设备描述表句柄。movetoex和lineto演示在dc上画一条直线记住,最后调用releasedc释放hdc资源。int releasedc(
    hwndhwnd,//你要控制的那个窗口的句柄,如果你在getdc函数传递的是null,现在还要传递null。
    hdc hdc//dc的句柄
    );编译运行程序,按下按钮,发现屏幕的左上角处画了一条直线。
      2、按钮idc_getdc_api的函数
     
    voidcdcdemodlg::ongetdcapi()
    {
      hdchdc=::getdc(m_hwnd);
      ::movetoex(hdc,0,0,null);
      lineto(hdc,200,50);
      ::releasedc(m_hwnd,hdc);
    }  这段代码与前一段代码唯一的区别是getdc的参数不再是null,而改为cwnd的成员变量m_hwnd,即对话框窗口的句柄。对比两段代码运行结果,深入体会api函数 getdc。
      3、按钮idc_getdc_cwnd的函数
     
    voidcdcdemodlg::ongetdccwnd()
    {
      cdc*pdc=getdc();
      pdc>moveto(0,0);
      pdc>lineto(200,100);
      releasedc(pdc);
    }  该段代码演示使用mfccwnd类的getdc函数和releasedc的方法,使用该方法在程序窗口中画图非常方便。为了避免获取和释放设备描述表所带来的麻烦,mfc提供了一些cdc派生类,如cpaintdc,cclientdc,cwindowdc,这些类被设计为可直接进行实例化。各个类的构造函数和析构函数调用相应的函数捕获和释放设备描述表,从而使得更加方便简捷。
      4、按钮idc_cclientdc的函数
    http://www.hackbase.com/lib/20070222/13807.html
    windows 程序设计中的设备描述表
    20090826 08:55
      从cdc 派生出四个功能更具体的设备描述表类。层次如图所示。
       
      下面,分别讨论派生出的四种设备描述表。
      ccientdc 
      代表窗口客户区的设备描述表。其构造函数cclientdc(cwnd *pwin)通过::getdc获取指定窗口的客户区的设备描述表hdc,并且使用成员函数attach把它和cclientdc对象捆绑在一起;其析构函数使用成员函数detach把设备描述表句柄hdc分离出来,并调用::releasedc释放设备描述表hdc。  
      cpaintdc 
      仅仅用于响应wm_paint消息时绘制窗口,因为它的构造函数调用了::beginpaint获取设备描述表hdc,并且使用成员函数attach把它和cpaintdc对象捆绑在一起;析构函数使用成员函数detach把设备描述表句柄hdc分离出来,并调用::endpaint释放设备描述表hdc,而::beginpaint和::endpaint仅仅在响应wm_paint时使用。  
      cmetafiledc 
      用于生成元文件。
      cwindowdc 
      代表整个窗口区(包括非客户区)的设备描述表。其构造函数cwindowdc(cwnd *pwin)通过::getwindowdc获取指定窗口的客户区的设备描述表hdc,并使用attach把它和cwindowdc对象捆绑在一起;其析构函数使用detach把设备描述表hdc分离出来,调用::releasedc释放设备描述表hdc。
      
      本文来自bcwhy论坛,转载请标明出处
      要使用设备描述表,一般有如下步骤:
      获取或者创建设备描述表;
      必要的话,改变设备描述表的属性;
      使用设备描述表完成绘制操作;
      释放或删除设备描述表。 
      common设备描述表通过::getdc,::getdcex,::beginpaint来获得一个设备描述表,用毕,用::releasedc或::endpaint释放设备描述表;
      printer设备描述表通过::createdc创建设备描述表,用::deletedc删除设备描述表。
      memory设备描述表通过::createcompatibledc创建设备描述表,用::deletedc删除。
      information设备描述表通过::createic创建设备描述表,用::deletedc删除
      


本文转载自:http://vaotoo.com/r/2940

共有 人打赏支持
小青_1989
粉丝 3
博文 75
码字总数 12913
作品 0
大连
程序员
私信 提问
详解DC、CDC、HDC、句柄、设备上下文

MFC中的DC、CDC、HDC、句柄、设备上下文究竟是什么意思? 在MFC程序中,我们并不经常直接调用Windows API,而是从MFC类创建对象并调用属于这些对象的成员函数.也就是说MFC封装了Windows API 你...

IMGTN
2012/06/04
0
0
【Visual C++】CDC与HDC的区别以及相互转换

CDC是MFC的DC的一个类 HDC是DC的句柄,API中的一个类似指针的数据类型. MFC类的前缀都是C开头的 H开头的大多数是句柄 这是为了助记,是编程读\写代码的好的习惯. CDC中所有MFC的DC的基类.常用的...

长平狐
2012/11/12
95
0
MFC绘图2-客户区大小和DC

MFC绘图2-客户区大小和DC 客户区大小和DC 在绘图前,必须先得到客户区大小和设备上下文DC。 1.获得客户区 绘图一般都是在视图窗口的客户区进行,而客户区的大小在运行时可由用户改变,为了使...

IMGTN
2012/06/10
0
0
VC++6.0中OpenGL应用程序开发

1. Win32控制台方式 建立Win32 控制台程序,在头文件中加入 2. MFC方式 (1)采用VC AppWizard向导创建空的MFC(EXE)工程框架,整个过程总共6步,值得指出的是一般情况下在向导的第1步选择创...

robslove
2015/04/06
0
0
CDC绘图总结

GDI总结:http://dingchaoqun12.blog.163.com/blog/static/11606250420112213396361/ 对话框 控件 视图类 应用程序框架都会调用该CWnd的消息响应成员函数(的覆盖)来绘制窗口客户区。 在Win...

长平狐
2012/10/08
2.4K
0

没有更多内容

加载失败,请刷新页面

加载更多

docker搞个wordpress

1.先把wordpress的镜像下载下来 docker pull wordpress 2.下载mysql docker pull mysql:lastest 3.启动mysql docker run --name blog -e root -d mysql:5.7 docker run --name some-mysql -e......

无极之岚
8分钟前
0
0
【宇润日常疯测-005】PHP 中的 clone 和 new 性能比较

clone和new本不应该放在一起比较,它们的作用是不同的。但可能有一些场景下,可以用clone也可以用new,那么这时候我们选哪个呢? 我编写了两个测试,第一个是声明一个空类,第二个是带构造方...

宇润
8分钟前
0
1
点击按钮弹出类似IOS 底部 dialog

implementation 'com.baoyz.actionsheet:library:1.1.7' 然后设置按钮点击监听,,调用下列代码即可 ActionSheet.createBuilder(this, getSupportFragmentManager()) ......

lanyu96
12分钟前
1
0
专访阿里云专有云马劲,一个理性的理想主义者

“我的故事都是和团队技术相关的,自己还真没有什么引人入胜的故事。”当马劲被问到能不能多分享些个人经历故事时他笑着说,我们就干脆怀着好奇聊了聊他和阿里云专有云一路走来的故事。 马劲...

阿里云官方博客
43分钟前
1
0
java环形缓冲区

import java.util.ArrayList;import java.util.List;/** * * 环形缓冲区<br/> * 一. 写数据:<br/> * 1. push: 当数据已写满时返回false,否则可以正常写入返回true<br/>......

whoisliang
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部