深入理解DC与窗口坐标系的关系

引入问题

前几天公司的实习生问了一个问题,点击按钮在窗口的子控件上显示图像,但是无法显示,咋一看代码没啥问题呀!
问题图片
原始代码如下:

// 预加载一张图片
CImage img;
img.Load(L"start_play.png");

// 获取窗口对象,及绘图区域
CWnd *pUI = GetDlgItem(IDC_STC_PIC);
CRect rt;
pUI->GetWindowRect(&rt);

// 获取画布,开始绘制
CDC *pDC = pUI->GetDC();
img.Draw(pDC->GetSafeHdc(), rt);

ReleaseDC(pDC);

分析问题

MFC在窗口上显示一张图片,从逻辑上看没有任何问题,加载资源 —— 获取画布及区域 —— 在画布上绘图。一般情况下,绘制但没显示,有2个原因:

  • 图片被设置为不可见;
  • 显示在画布之外;

经过代码调试发现,是DC对应的坐标系搞错了,CDC *pDC = pUI->GetDC()是获取子控件DC,是以控件左上角为坐标原点,而rt是相对于屏幕的矩形区域,要解决此问题,只需DC与坐标系相匹配即可。

解决问题

主要有2种方法:

  • 修改DC
// 获取桌面DC,对应屏幕坐标系
CDC *pDC = GetDesktopWindow()->GetDC();
  • 修改坐标系
// 屏幕坐标系 -> 子控件坐标系
img.Draw(pDC->GetSafeHdc(), CRect(0, 0, rt.Width(), rt.Height()));

问题延申

我们在一个控件上绘图时,会涉及到3种DC(画布),对应三种坐标系。

  1. 桌面(屏幕)DC,以屏幕左上角为坐标原点;
  2. 窗口DC,以应用程序窗口左上角为坐标原点;
  3. 子控件DC,以子控件左上角为坐标原点;

所以,我们在解决此问题时,要以画布为基准,去匹配正确的坐标点。下图为DC与坐标系的对应图:
在这里插入图片描述
理清这层关系后,就有了第三种方法:

// 将屏幕坐标,转成主窗口坐标
ScreenToClient(&rt);

// 获取的是主窗口DC
CDC *pDC = GetDC();

如果文章对您有帮助,记得点个赞哈!即是鼓励,也是提醒我坚持下去的动力~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值