详解DCCDCHDC句柄设备上下文.docx

上传人:b****5 文档编号:3653404 上传时间:2022-11-24 格式:DOCX 页数:18 大小:32.87KB
下载 相关 举报
详解DCCDCHDC句柄设备上下文.docx_第1页
第1页 / 共18页
详解DCCDCHDC句柄设备上下文.docx_第2页
第2页 / 共18页
详解DCCDCHDC句柄设备上下文.docx_第3页
第3页 / 共18页
详解DCCDCHDC句柄设备上下文.docx_第4页
第4页 / 共18页
详解DCCDCHDC句柄设备上下文.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

详解DCCDCHDC句柄设备上下文.docx

《详解DCCDCHDC句柄设备上下文.docx》由会员分享,可在线阅读,更多相关《详解DCCDCHDC句柄设备上下文.docx(18页珍藏版)》请在冰豆网上搜索。

详解DCCDCHDC句柄设备上下文.docx

详解DCCDCHDC句柄设备上下文

请问MFC中的DC、CDC、HDC、句柄、设备上下文究竟是什么意思?

希望能解答详细一点点谢谢了

楼主你没有了解MFC的运行机制就去看他写他所以你先要了解他的机制已经各个CPP.H都是什么

下面我就给你说下

在MFC程序中,我们并不经常直接调用WindowsAPI,而是从MFC类创建对象并调用属于这些对象的成员函数.也就是说MFC封装了WindowsAPI你说你喜欢C++而MFC换一种说法就是一个用C++写的一个函数库然后你来调用只不过这个类不是你写的

MFC提供数百个类,最重要的、也是编写任何VC++应用程序都必不可少的两个类CWinApp和CFrameWnd,这两个类是编写复杂庞大应用程序的基石。

1>封装特性:

构成MFC框架的是MFC类库而MFC类库又是C++的一个类库。

这些类封装WIN32应用程序编程接口,OLE(ObjectLinkEmbed对象链接嵌入)特性,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

}

MFCObject和WindowsObject的对应关系:

描述Windows句柄MFCObject

窗口HWNDCWnd

设备上下文HDCCDC

菜单HMENUCMenu

笔HPENCPen

刷子HBRUSHCBrush

字体HFONTCFont

位图HBITMAPCBitmap

套接字SOCKETCSocket

三、手工创建一个MFC应用程序:

注意:

创建MFC程序,要创建一个Win32空项目,并要选择项目属性中的”在共享DLL文件中使用MFC,然后新建我们的文件

例子:

在”hello.h”头文件中添写如下代码:

classCMyApp:

publicCWinApp

{

public:

virtualBOOLInitInstance();//虚函数

};

classCMainWindow:

publicCFrameWnd

{

public:

CMainWindow();

protected:

afx_msgvoidOnPaint();

DECLARE_MESSAGE_MAP();//声明消息映射

};

在”hello.cpp”源文件中添写如下代码:

#include

#include“hello.h"

CMyAppmyApp;

BOOLCMyApp:

:

InitInstance()

{

m_pMainWnd=newCMainWindow;

m_pMainWnd->ShowWindow(m_nCmdShow);

m_pMainWnd->UpdateWindow();

returnTRUE;

}

BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)

ON_WM_PAINT()

END_MESSAGE_MAP()//消息映射

CMainWindow:

:

CMainWindow()//构造函数初始化

{

Create(NULL,“我的第一个MFC应用程序”);//创建窗体

}

voidCMainWindow:

:

OnPaint()

{CPaintDCdc(this);

CRectrect;

GetClientRect(&rect);

dc.DrawText("HelloMFC",-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);

}

CWinApp是应用程序类,在MFC应用程序中必须从这个类派生出一个类,该派生类是MFC应用程序的入口

必须定义这个派生类的对象,并且只能有一个这个对象代表整个应用程序。

成员函数:

InitInstance()

功能:

初始化应用程序实例和窗口实例,

虚函数CWinApp:

:

InitInstance必须在派生类中重写。

在InitInstance函数中,编写初始化代码,如:

创建一个窗口

显示一个窗口

CFrameWnd类

作用:

为应用程序提供一个窗口,同时实现消息处理功能。

成员函数:

Create()

功能:

创建窗体,将之赋于CFrameWnd对象上。

BOOLCreate(窗口类型,窗口标题,显示风格,显示区域,符窗口句柄,菜单,扩展显示风格,上下文对象)共有8个参数,前两个必须给出,后6个可以默认。

MFC应用程序的核心就是基于CWinApp类的应用程序对象,CWinApp提供了消息循环来检索消息并将消息调度给应用程序的窗口.我们在编写MFC应用程序时,要包含afxwin.h,

一个MFC应用程序可以有且仅有一个应用程序对象,对象必须声明为在全局范围内有效(也就是全局对象),以便它在程序开始时即在内存中被实例化

我们的HelloMFC的应用程序类被命名为CMyApp,它在hello.cpp中用如下语句进行了实例化:

CMyAppmyApp;

CMyApp的类声明在hello.h中代码如下:

classCMyApp:

publicCWinApp

{

public:

virtualBOOLInitInstance();

};

CMyApp没有声明任何的数据成员,只是重写了一个从CWinApp类中继承来的函数,在应用程序的生存期内InitInstance的调用比较早,是在应用程序开始运行以后而窗口创建之前,除非InitIstance创建一个窗口,否则应用程序是不会有窗口,这正是为什么即使最小的MFC应用程序也必须从CWinApp派生出一个类并重写CWinApp:

:

InitIstance的原因

InitInstance函数:

CWinApp:

:

InitInstance是一个虚函数,其默认操作仅包含一条语句:

returnTRUE;

InitInstance是用来执行程序每次开始时都需要进行的初始化工作最好的地方

在hello.cpp中,CMyApp的InitInstance通过实例化hello的CMainWindow类来创建hello窗口,语句:

m_pMainWnd=newCMainWindow;

构造了一个CMainWindow对象指针,并将其地址复制到了应用程序对象的m_pMainWnd数据成员中,窗口创建以后,InitInstance就会通过CMainWindow指针调用ShowWindow和UpdateWindow函数显示它:

m_pMainWnd->ShowWindow(m_nCmdShow);

m_pMainWnd->UpdateWindow();

ShowWindow和UpdateWindow是所有窗口对象共用的CWnd成员函数其中包括CFrameWnd类的对象,CMainWindow就是从CFrameWnd派生出来的.

要从MFC程序调用一个常规的WindowsAPI函数,需要在函数名称前添加一个全局运算符:

:

例如:

:

:

UpdateWindow();

通过生成窗口对象并调用其Create函数,MFC应用程序可以创建一个窗口,在CMyApp:

:

InitInstance中,hello创建了一个CMainWindow对象,CMainWindow的构造函数生成在屏幕上看到的窗口:

Create(NULL,”我的第一个MFC应用程序”);

CPaintDCdc(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采用消息映射(MessageMap)机制取代C/C++语言中的switch-case结构来处理消息。

消息映射:

在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_msgvoidOnPaint();

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

BSTR32为字符指针

BYTE8位整数无符号的

COLORREF32位数值代表一个颜色值

DWORD32位整数无符号的

LONG32位整数带符号的

LPCTSTR32位指针,指向一个常字符串

LPVOID32位指针,指向一个为指定类型的数据

MFC特有的数据类型:

1>POSITION:

一个数值,代表数组或者链表中元素的位置,在MFC中常用于数据处理类

2>LPRECT:

32位指针,指向一个不变的矩形区域结构

 

这是我针对你的问题整理的一些资料很多我想删减一些但我觉得这些都对你很重要

关于CDC(设备上下文)HDC

C/C++2008-02-2922:

28:

01阅读79评论0  字号:

大中小 订阅

 

可以简单的如此理解:

DC(DEVICECONTEXT),就是设备描述表(或者叫做设备环境),就像你作画,需要用到画笔,画刷,颜料等等,这些东西就是作画的环境,属于设备DC的属性所有,想作图就先把作图环境准备一下,这跟我们作画是一样的道理。

 

CDC和HDC简单使用:

CDC是设备上下文类;

HDC是设备上下文句柄;

//CDC-->HDC与HDC->CDC

CDCdc;

HDChdc;

hdc=dc.m_hDC;

dc=CDC:

:

FromHandle(hdc);

//or hdc=dc.GetSafeHdc();

 

挂一段正规文档(来源MSDN):

设备上下文

设备上下文是一种包含有关某个设备(如显示器或打印机)的绘制属性信息的Windows数据结构。

所有绘制调用都通过设备上下文对象进行,这些对象封装了用于绘制线条、形状和文本的WindowsAPI。

设备上下文允许在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;

 

下面一段翻译自MSDNSDK文档

   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对象,在从物理设备读取属性期间向元文件发送输出。

打印预览以相同风格在框架中实现。

还可以以相似方法在特殊应用代码中使用这两个设备上下文。

    

CDC、HDC、pDC(zz)

MFC2009-12-0222:

44:

01阅读275评论0  字号:

大中小 订阅

1.CDC*pDC和HDChdc有什么不同,类似的有CWnd*pWnd和HWnd?

pDC是类指针

HDC是windows句柄

通过pDC获得hdc:

HDChdc=pDC->GetSafeHdc();

通过hdc获得pDC:

CDC*pDC=newCDC;

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(intx,inty,constCString&str)

{

    TextOut(m_hDC,x,y,(LPCTSTR)str,str.GetLength());

}

m_hDC就是CDC的成员变量HDCm_hDC;

CDC有一个operatorHDC()const{returnm_hDC;}  

你可以把它当成一个HDC使用

3.this是dc输出目标窗口的指针,通过它可以得到窗口句柄

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1