关于DC的一个小疑问

Guy_Fwakes 2014-11-29 09:00:25
对话框过程中执行了如下代码

//hDialog是对话框窗口句柄
hParent = GetParent(hDialog);
//修改父窗口的DC,iColor[ ]是0~255的数组,通过滚动条控制
hdc = GetDC(hParent);
DeleteObject(SelectObject(hdc,
CreateSolidBrush(RGB(iColor[0],iColor[1],iColor[2]))));
ReleaseDC(hParent,hdc);

InvalidateRect(hParent,NULL,TRUE);
UpdateWindow(hParent);

然后在主窗口的消息处理函数中,有如下代码

case WM_PAINT:
hdc = BeginPaint(hWnd,&ps); /
GetClientRect(hWnd,&rect);
Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom);
EndPaint(hWnd,&ps);
return 0;

那么问题来了:
执行后却没有按照对话框过程中的修改的hBrush重绘主窗体的客户区,为什么?

不要告诉我另外可行的方法,我只是针对这个DC的问题:
1如果对话框中直接修改DC中的hBrush后直接重绘是可以的
2,通过SetClassLong修改GCL_HBRBACKGROUND,再引发重绘消息也是可以的
...全文
275 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohuh421 2014-12-01
  • 打赏
  • 举报
回复
1. 首先你要保证有WM_PAINT产生, 因为只有这样才会有机会执行你的代码 2. 由于WM_PAINT消息来之前, 全部东西都会被擦除掉的. WM_PAINT来的DC也相当于是一个空的DC. 一般是纯黑色背景. 所以你需要在每次Rectangle前, 重新选择画刷到DC中. 代码修改如下. case WM_PAINT: hdc = BeginPaint(hWnd,&ps); / GetClientRect(hWnd,&rect); HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0)); HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hBrush); Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom); ::SelectObject(hdc, hOldBrush); ::DeleteObject(hBrush); EndPaint(hWnd,&ps); return 0;
Guy_Fwakes 2014-12-01
  • 打赏
  • 举报
回复
引用 8 楼 Daisy__Ben 的回复:
看不懂,为毛lz自己都说其它方法可以做到重绘,还要用修改dc的方法。难道lz是想研究dc的内部机制吗,我想请问lz在响应WM_PAINT消息时为什么要BeginPaint(hWnd,&ps);
其实我只是想知道DC的作用范围,是不是全局有效的,就是如果我在子函数中修改了DC的画刷或者画笔,最后能否保存,这样在我下一次调用的时候我就可以直接使用 至于BeginPaint的作用应该是移除消息队列中的WM_PAINT消息,获取PAINTSTRUCT结构体,获取DC吧?
Sandrer 2014-12-01
  • 打赏
  • 举报
回复
引用 6 楼 nemyth 的回复:
[quote=引用 2 楼 Sandrer 的回复:] 子窗口子类化父窗口,然后拦截父窗口的 WM_PAINT 行不行
真巧,又碰到你在线,非常感谢你上次的帮助,还想问你一下,RibbonBar上的标签切换时,会触发什么事件呢? 想实现一个根据标签,隐藏指定上下文选项卡的功能。 最近在用Vs2013写一个Ribbon风格的本地化应用,对Ribbon资源控件的使用上屡屡碰壁。[/quote] 我刚从vs2005转到2010, 还没接触过RibbonBar 你自己用 spy++ 拦截试试
Daisy__Ben 2014-12-01
  • 打赏
  • 举报
回复
看不懂,为毛lz自己都说其它方法可以做到重绘,还要用修改dc的方法。难道lz是想研究dc的内部机制吗,我想请问lz在响应WM_PAINT消息时为什么要BeginPaint(hWnd,&ps);
呆老呆 2014-11-30
  • 打赏
  • 举报
回复
引用 2 楼 Sandrer 的回复:
子窗口子类化父窗口,然后拦截父窗口的 WM_PAINT 行不行
真巧,又碰到你在线,非常感谢你上次的帮助,还想问你一下,RibbonBar上的标签切换时,会触发什么事件呢? 想实现一个根据标签,隐藏指定上下文选项卡的功能。 最近在用Vs2013写一个Ribbon风格的本地化应用,对Ribbon资源控件的使用上屡屡碰壁。
Guy_Fwakes 2014-11-30
  • 打赏
  • 举报
回复
引用 1 楼 Sandrer 的回复:
先不说能否通过你的方法来更改 在你的代码中就看到有3个错误 1、SelectObject 返回的 GDI 对象,除非是你建立的,否则不要 DeleteObject,需要先保存起来 2、不是你创建的 dc,SelectObject 后需要把原来的 GDI 对象重新选入 dc(就是第1点所说的) 3、CreateSolidBrush 创建的 GDI 对象你没有释放,造成资源泄漏 你所说的问题,可能是 GetDC 返回给你的只是一个系统临时建立的内存 DC 你单步调试时看看 GetDC 获得的 dc 与父窗口中 BeginPaint 获得的 dc 看是否一致
通过调试确实两次获得的DC是不同的值,有点“反直觉”,如果你有这方面的解释希望能够交流下
信阳毛尖 2014-11-30
  • 打赏
  • 举报
回复
更何况,WM_PAINT消息的发送并不完全由你自己控制,也就是说,窗口在OnPaint的时候,你能保证你的这段代码 //hDialog是对话框窗口句柄 hParent = GetParent(hDialog); //修改父窗口的DC,iColor[ ]是0~255的数组,通过滚动条控制 hdc = GetDC(hParent); DeleteObject(SelectObject(hdc, CreateSolidBrush(RGB(iColor[0],iColor[1],iColor[2])))); ReleaseDC(hParent,hdc); InvalidateRect(hParent,NULL,TRUE); UpdateWindow(hParent); 执行过了吗??
信阳毛尖 2014-11-30
  • 打赏
  • 举报
回复
你这个逻辑就是错误的 “如果对话框中直接修改DC中的hBrush后直接重绘是可以的” 这才是正确的逻辑 hdc = GetDC(hParent); DeleteObject(SelectObject(hdc, CreateSolidBrush(RGB(iColor[0],iColor[1],iColor[2])))); ReleaseDC(hParent,hdc); 你的这句中,你以为的SelectObject(hdc, CreateSolidBrush(RGB(iColor[0],iColor[1],iColor[2])就是改变了源hdc中的默认brush了吗?? 自己测试一下吧: hdc = GetDC(hParent); HBRUSH hBrush = CreateSolidBrush(RGB(iColor[0],iColor[1],iColor[2]); SelectObject(hdc,hBrush); ReleaseDC(hParent,hdc); case WM_PAINT: hdc = BeginPaint(hWnd,&ps); / GetClientRect(hWnd,&rect); HOBJECT hObj = SelectObject(hdc,(HBRUSH)::GetStockObject(NULL_BRUSH)); Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom); EndPaint(hWnd,&ps); return 0; 你看看那个hBrush 和hObj是一个东东吗?
Sandrer 2014-11-29
  • 打赏
  • 举报
回复
子窗口子类化父窗口,然后拦截父窗口的 WM_PAINT 行不行
Sandrer 2014-11-29
  • 打赏
  • 举报
回复
先不说能否通过你的方法来更改 在你的代码中就看到有3个错误 1、SelectObject 返回的 GDI 对象,除非是你建立的,否则不要 DeleteObject,需要先保存起来 2、不是你创建的 dc,SelectObject 后需要把原来的 GDI 对象重新选入 dc(就是第1点所说的) 3、CreateSolidBrush 创建的 GDI 对象你没有释放,造成资源泄漏 你所说的问题,可能是 GetDC 返回给你的只是一个系统临时建立的内存 DC 你单步调试时看看 GetDC 获得的 dc 与父窗口中 BeginPaint 获得的 dc 看是否一致

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧