CClientDC 解说及举例

MFC 画线 CDC类 /*CDC *pDC=GetDC(); pDC->MoveTo(m_ptOrigin); pDC->LineTo(point); ReleaseDC(pDC);*/ CClientDC类 //CClientDC dc(this); /*CClientDC dc(GetParent()); dc.MoveTo(m_ptOrigin); dc.LineTo(point) 阅读详情
CClientDC类的成员
构造函数
CClientDC构造一个连接到CWnd上的CClientDC对象

数据成员
m_hWnd CClientDC所在的有效窗口的HWND

成员函数
CClientDC::CClientDC
CClientDC(CWnd* pWnd );
throw( CResourceException );
参数
pWnd设备上下文将要存取的客户区所在的窗口。
说明
本函数构造一个CClientDC对象,它将存取pWnd指向的CWnd的客户区。此构造函数调用了Windows函数GetDC。如果Windows函 数GetDC调用失败,则产生一个CResourceException类型的异常。如果Windows已经分配出了所有可用的设备上下文,则没有新的设 备上下文可用。无论何时,应用总在竞争使用Windows提供的五个公共显示上下文。

数据成员
CClientDC::m_hWnd
说明
m_hWnd是一个保护的变量,是用来构造m_hWnd对象的CWnd指针的HWND。  

 

==============================================================


几种DC及区别
  

CClientDC:(客户区设备上下文)用于客户区的输出,与特定窗口关联, 可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函 数中包含了ReleaseDC:

CClientDC::CClientDC(CWnd* pWnd)
{
     ...
     if (!Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd())))
         AfxThrowResourceException();
}

CClientDC::~CClientDC()
{
     ...
     ::ReleaseDC(m_hWnd, Detach());
}
用法是:
CClientDC dc(this);//this一般指向本窗口或当前活动视图
dc.TextOut(10,10,str,str.GetLength());//利用dc输出文本,如果是在
CScrollView中使用,还要注意调用OnPrepareDC(&dc)调整设备上下文的
坐标。
CPaintDC用于响应窗口重绘消息(WM_PAINT)是的绘图输出。
CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中 调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还 负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须 使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不 断的窗口重画。CPaintDC也只能用在WM_PAINT消息处理之中。

CPaintDC::CPaintDC(CWnd* pWnd)
{
     ...
     if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))
         AfxThrowResourceException();
}

CPaintDC::~CPaintDC()
{
     ...
     ::EndPaint(m_hWnd, &m_ps);
     Detach();
}
CWindowDC:关联一特定窗口,允许开发者在目标窗口的任何一部分进行
绘图,包含边界与标题,这种DC同WM_NCPAINT消息一起发送

CWindowDC与CClientDC,CPaintDC的区别:
CWindowDC可在非客户区绘制图形,而CClientDC,CPaintDC只
能在客户区绘制图形。
CWindowDC下坐标原点是在屏幕的左上角,CClientDC,CPaintDC
下坐标原点是在客户区的左上角。
CClientDC与CPaintDC的区别:

CPaintDC的对象一般用在OnPaint内以响应Windows消息WM_PAINT, 自动完成绘制,在整个窗口内进行重画,
维持原有窗口完整性。
CClientDC应用在非响应Windows消息WM_PAINT的情况下,进行实时
绘制,绘制的区域内被重画。


====================================================================


VC中MFC下的绘图初步解析

 

作者:zieckey( zieckey@yahoo.com.cn )
All Rights Reserved!

首先我们说下通过鼠标的移动来绘制直线。
这里要捕获到鼠标的两个消息:WM_LBUTTONDOWN, WM_LBUTTONUP
响应WM_LBUTTONDOWN消息记录直线的起始点,响应WM_LBUTTONUP消息记录直线的终点并绘制直线。
好了,我们看看怎么响应。
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
//MessageBox("Left Button Clicks DrawView");
m_ptOrigin = point ;         //这里先定义了一个内部变量保存直线的起始点
CView::OnLButtonDown(nFlags, point);
}


下面看看响应WM_LBUTTONUP消息记录直线的终点并绘制直线。

//方法一
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
HDC hdc;
hdc = ::GetDC(m_hWnd); //调用全局函数
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,0);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);
CView::OnLButtonUp(nFlags, point);
}
//方法二
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
CDC *pDC = GetDC();
pDC->Move

To(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);
}
//方法三
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
CClientDC dc(this) ;    //CClientDC对象构造的时候就调用了GetDC,析构的时候调用

ReleaseDC ,只能访问客户区
CClientDC dc(GetParent());
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
}
//方法四
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
CWindowDC dc(this) ;   //CWindowDC可以访问客户区和非客户区
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
}
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
CWindowDC dc(GetDesktopWindow()) ;   //现在可以访问桌面
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
}


连续线绘图:
思路:鼠标移动的信号被捕捉到,然后随时响应该信号,绘制图线
这里要设置一个BOOL变量 m_bDraw 来判断是否鼠标左键按下了。

//画连续的线条
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
if ( m_bDraw )
{
   CClientDC dc(this) ;
   dc.MoveTo(m_ptOrigin);   //移动到原来的点
   dc.LineTo(point); //绘制直线
   m_ptOrigin = point ; //将现在的点赋值给原来的坐标,以便下次调用
}
CView::OnMouseMove(nFlags, point);
}

//改变画笔的颜色
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
if ( m_bDraw )
{
   CClientDC dc(this) ;
   CPen pen( PS_SOLID , 1 , RGB(255,128,128) );
   CPen *pOldPen = dc.SelectObject(&pen);
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(point);
   m_ptOrigin = point ;
   dc.SelectObject(pOldPen);
}
CView::OnMouseMove(nFlags, point);
}

//画扇型
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
if ( m_bDraw )
{
   CClientDC dc(this) ;
   CPen pen( PS_SOLID , 1 , RGB(255,128,128) );
   CPen *pOldPen = dc.SelectObject(&pen);
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(m_ptOld);
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(point);
   m_ptOld = point ;
   dc.SelectObject(pOldPen);
}
CView::OnMouseMove(nFlags, point);
}

 

//画带边线的扇型
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{

if ( m_bDraw )
{
   CClientDC dc(this) ;
   CPen pen( PS_SOLID , 1 , RGB(255,128,128) );
   CPen *pOldPen = dc.SelectObject(&pen);
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(m_ptOld);
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(point);
   dc.MoveTo(m_ptOld);
   dc.LineTo(point);
   m_ptOld = point ;
   dc.SelectObject(pOldPen);
}
CView::OnMouseMove(nFlags, point);
}

//看看绘图的模式设置方法
void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
if ( m_bDraw )
{
   CClientDC dc(this) ;
   dc.SetROP2(R2_BLACK);   //绘图的模式设置,始终绘制黑色图形
   CPen pen( PS_SOLID , 1 , RGB(255,128,128) );
   CPen *pOldPen = dc.SelectObject(&pen);
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(m_ptOld);
   dc.MoveTo(m_ptOrigin);
   dc.LineTo(point);
   dc.MoveTo(m_ptOld);
   dc.LineTo(point);
   m_ptOld = point ;
   dc.SelectObject(pOldPen);
}

CView::OnMouseMove(nFlags, point);
}

到此,我们知道了一般地绘图方法了。

 

==============================================


图像文件相关操作

1,显示一张位图:

int CThreadPoolDlg::ShowFace(int xPos, int yPos, CString FilePath)
{
// TODO: Add your control notification handler code here
CClientDC *pDC = new CClientDC(this);
CBitmap Bitmap;
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,FilePath,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
Bitmap.Attach(hBitmap);
CDC DCCompatible;
DCCompatible.CreateCompatibleDC(pDC);
DCCompatible.SelectObject(&Bitmap);
BITMAP bmInfo;
Bitmap.GetObject(sizeof(bmInfo),&bmInfo);
pDC->BitBlt(xPos,yPos,bmInfo.bmWidth,bmInfo.bmHeight,&DCCompatible,0,0,SRCCOPY);
return 1;

VC++ 绘制线条 OnLButtonDown函数(DrawView.cpp) 利用SDK全局函数实现画线功能 利用MFC的CDC类实现画线功能 利用MFC的CClientDC类实现画线功能 绘制线条 了解了MFC的消息映射机制,下面我们就来完成画线功能。在先前创建的Draw项目中,可以看到消息响应函数OnLButtonDown有两个参数(如例5-2所示),其中第二个参数是CPoint类型,CPoint类表示一个点。也就是说,当按下鼠标左键时,鼠标单击处的坐标点已由此参数传递给 OnLButtonDown 这一消息响应函数。这样,我们所需要做的工作就是在此消息响应函数中保存该点的信息。为此,需要在视类中增加一个成员变量。给一个类增加成员变量可以通过在类视图中用鼠标右键单击该类,并从弹出的快捷菜 阅读详情

相关推荐

VC_MFC的HDC,CDC,CWindowDC,CClientDC,CPaintDC详解

VC_MFC的HDC,CDC,CWindowDC,CClientDC,CPaintDC详解

MFC保存BMP、JPG、PNG图片

最近用户反映软件里面的图片保存只有bmp格式,体验不好,需要添加jpg和png。那么就来改一改吧。 一、添加工具类CSaveHelper。 #pragma once class CSaveHelper { public: CSaveHelper(); ~CSaveHelper(); public: int Save(CWnd* pWnd, CString filePath); }; in...

Struggling_Jeff的博客 2687

Linux下安装FastDFS及生成缩略图

1. 安装编译环境 yum install git gcc gcc-c++ make automake vim wget libevent -y 2. 安装libfastcommon基础库 mkdir /root/fastdfs cd /root/fastdfs git clone https://github.com/happyfish100/libfastcommon.git --depth 1 cd libfastcommon/ ./make.sh && ./make.sh ins

weixin_45234710的博客 1374

CClientDC 解说及举例(转)

CClientDC 解说及举例 CClientDC 解说及举例 类CClientDC派生于CDC,在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC。这意味着和CClientDC对象相关的设备上下文是窗口的客户区。要了解有关CClientDC的更详细的信息,请参阅联机文档“Visual C++程序员指南斨械摹吧璞干舷挛臄部分。#include

风云爱飞 1020

ACS驱动器直线电机回零程序与误差补偿Buffer实战解析

本文深入解析了ACS驱动器控制直线电机时,实现高精度回零与误差补偿的完整实战流程。核心在于利用驱动器的D-Buffer功能,将激光干涉仪测量的误差数据导入补偿数组,通过ERRORMAP1D指令进行映射,从而实时修正定位误差,显著提升设备重复定位精度。文章详细拆解了回零程序逻辑、补偿参数设置及关键调试避坑指南。

648

基于近场动力学的二维疲劳裂纹扩展模型_近场动力学数值模拟的程序实现(1)——引言...

参考书目W. H. Gerstle. 2015. Introduction to Practical Peridynamic: Computational Solid Mechanics Without Stress and Strain.E.Madenci, A.Barut, M.Dorduncu. Peridynamic Differential Operator for Numerical ...

weixin_39764603的博客 1202

MFC获取DC的四种方式

1)API函数方法用HDC hdc; hdc=::GetDC(m_hWnd); MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL); LineTo(hdc,point.x,point.y); ::ReleaseDC(m_hWnd,hdc);//必须成对使用 这里获得GetDC()函数需要跟ReleaseDC()函数成对使用

ucnioa的专栏 6507

避坑指南:Unity新版InputSystem在移动端的5个常见问题及解决方案

本文针对Unity新版InputSystem在移动端开发中的常见问题,提供了5个关键解决方案,包括虚拟摇杆灵敏度调节、多点触控冲突处理、按钮反馈延迟优化、手势识别与陀螺仪数据融合以及Android/iOS平台差异处理。这些实战经验帮助开发者高效解决触控适配难题,提升移动游戏体验。

soda5的博客 405

CClientDC类 CWindowDC类

CClientDC类 CClientDC类也是CDC类的派生类。它只能在窗口的客户区(即窗口中除了边框、标题栏、菜单栏以及状态栏外的中间部分)中进行绘图,坐标点(0,0)通常指的是客户区的左上角。它的构造函数调用GegDC函数,而析构函数调用ReleaseDC函数。 CClientDC(客户区设备上下文)用于客户区的输出,它在构造函数中封装了GetDC(),在析构函数中封装了R...

aizongsai2251的博客 600

12V INPUT电源电路设计中的关键保护机制解析【精简】

本文深入解析了12V INPUT电源电路设计中不可或缺的关键保护机制。针对常见的电源反接、过压及浪涌等风险,文章详细拆解了PMOS防反接、TVS过压钳位、OVP芯片关断以及快速断电电路等核心防护方案的设计原理、选型要点与实战优化技巧,旨在帮助工程师构建可靠、经济的电源前端防御体系。

weixin_29158047的博客 228

一文速览:大模型语料构建与基础训练全流程实战指南

因为模型只有看到足够丰富、高质量的数据,才能真正学到“真本事”,展现出更强大的泛化能力,也就是能够在全新的场景和任务下,做出准确的推理和判断。我们日常做饭的时候,通常会先把买回来的菜仔细清洗干净,把坏掉的叶子、泥土、杂质等去除掉。同理,训练大模型的数据就像我们的食材,如果不干净,就会影响模型的学习效果,甚至训练出逻辑紊乱的模型。在大模型的世界里,有一句名言:“Garbage in, Garbage out”,翻译过来就是“垃圾输入,垃圾输出”,说白了,就是给模型喂的是什么数据,它学到的就是什么知识。

master_hunter的博客 1671

MFC.3 static CDC *pMainDC = new CClientDC(this)

我刚才想到一个问题 利用HDC 或其子类构造函数在堆区实例了一个对象是可以但是 窗口表面位置是会变的 也就是说如果一直用哪一个堆区DeviceContent对象是不行的 然后我看了一下我的程序有点问题 CDC *pMainDC = new CClientDC(this) 是在OnPaint()函数里每次都执行了这个 是可以和窗口的数据同步但是会有很多堆区对象浪费 什么时候释放呢pM...

qq_40272523的博客 287

【OpenFOAM】-olaFlow-算例10-wavemakerTank

采用 Flap和Piston两种方式的动网格进行造波

ou_no的博客 2167

位图显示

读位图资源并显示 //1、准备设备dc CClientDC *pDC = new CClientDC(this); //2、准备内存dc CDC memDC; memDC.CreateCompatibleDC(pDC); //3、加载资源位图 CBitmap bmp; bmp.LoadBitmap(IDB_BITMAP1); //4、将资源位图选进内存dc HGDIOBJ hO

zhangtaohbwh的博客 468

OpenClaw 技术架构解析-网关层(上)

OpenClaw 网关层是架构核心中枢,承接Channel层消息,串联消息路由器、会话状态管理器等五大组件,负责消息分发、会话管理、状态统筹、上下文维护等关键职责,是连接Channel层与AI执行引擎的核心桥梁,保障多渠道交互稳定、有序运行。

wend的博客 713

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【vc】CPaintDC, CClientDC与CWindowDC的区别

问: 小乔我有个问题。CPaintDC是一种怎样的DC?就像CClientDC是客户区的,它是干什么的?还有msdn上说当有更新窗口或者重绘窗口消息发生时调用OnPaint函数,那又是怎么知道有更新和重绘这两个消息的呢(我没有在程序里显式的指出,似乎是自己发生的)? 谢谢啦  答: CPaintDC, CClientDC与CWindowDC的区别 CClientDC(客户区

jianxiong8814的专栏 3571

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

VC++ - 各种DC及DC资源释放

2013-04-18 16:58:57|  分类: GDI |  标签:cclientdc与cpaintdc  dc释放  dc  |字号 订阅 CClientDC dc(this); CPaintDC dc(this); 从前面我们可以得出,这两个语句就是新建dc变量并把当前的CWnd或其派生类的句柄得到当前窗体的作画区域放在dc这个变量中。

mituan1234567的专栏 6444

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

CClientDC类

类CClientDC派生于CDC,在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC。这意味着和CClientDC对象相关的设备上下文是窗口的客户区。 几种DC及区别   CClientDC:(客户区设备上下文)用于客户区的输出,与特定窗口关联,可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC:   用法

zcl_wish的专栏 4689

CPaintDC类与 CClientDC类的区别

CPaintDC 与 CClientDC   CPaintDC 与 CClientDC都是从CDC类继承而来。所以,这两个类的外在行为高度的抽象一致。以致于初者会误以为两者的使用可以替换(或者说MFC初学者很容易将两者的使用混淆)。事实上,MFC将两者都从CDC继承,是为了让用户在不同的场景下更加方便,高效的使用DC。如果不理解两者内部运作原理,混淆使用,就会出现屏幕绘制不能达到客户调用结果

gencheng的专栏 6552
下一篇: 如何更改cmd命令提示符的默认当前路径
un_loading
博客等级 码龄17年 4粉丝 4原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值