DC的几个概念啊

chouxiaoya8100 2011-10-06 08:48:37
发过贴,但是没有解答清楚,再次发帖,希望一次性搞清楚,谢谢大家发言啊。。。呵呵



对于

对于void COwnerDrawListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);


是该RealseDC 还是Detach 合适?




第2个问题:

对于CDialog::OnPaint, 用CDC好,还是CPaintDC好??


第3个问题:

DC 最终是windows回收的, 那么为什么要用户手动释放DC呢??

比如: void COwnerDrawListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

DRAWITEMSTRUCT 有个成员是HDC,

意味着ListBox的每一行都有一个DC的句柄,否则HDC是哪里来的???

谁给它的,是windows给它的, 既然给了它,那么FromHandle 起到的作用仅仅是

由句柄获得指针而言的作用啊, 那么为什么要Deatch 或者RealseDC ???

岂非多此一举??
...全文
147 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
chouxiaoya8100 2011-10-08
  • 打赏
  • 举报
回复
多谢多谢
星羽 2011-10-07
  • 打赏
  • 举报
回复
DC 是一个有点复杂的东西,它还存在着 common, class, private 3种类型
你要都搞清楚的话,最好把msdn里的关于dc的都看一下,或者google一下有没有详解dc的资料
星羽 2011-10-07
  • 打赏
  • 举报
回复
1) CDC::FromHandle
If a CDC object is not attached to the handle, a temporary CDC object is created and attached.
The pointer may be temporary and should not be stored beyond immediate use.


如果放回的是临时的CDC,MFC会在OnIdle的时候适当清理,你也可以手动调用CDC::DeleteTempMap()
至于要不要ReleaseDC,就看你的HDC是怎么来的

2)按msdn的这个说法
A CPaintDC object can only be used when responding to a WM_PAINT message, usually in your OnPaint message-handler member function.

OnPaint里应该使用CPaintDC

PS:CPaintDC是CDC的派生类
推荐你看看这个http://apps.hi.baidu.com/share/detail/20176633

3)GDI OBJECT 存在着引用计数,所以需要ReleaseDC
比如你使用了GetDC,用完后就需要Release
3)





zuo187qiang 2011-10-07
  • 打赏
  • 举报
回复
接分...up
chouxiaoya8100 2011-10-07
  • 打赏
  • 举报
回复
CPaintDC 用在OnPaint中, 也只能用在这个中,如果用其他DC,那么会引起不断的重画,

会影响程序吧,

这个是一些总结。。。。


CDC GetSafeHwnd() FromHandle 是句柄和指针的相互转换。。。。

  • 打赏
  • 举报
回复
CDC::DeleteTempMap Called by the CWinApp idle-time handler to delete any temporary CDC object created by FromHandle. Also detaches the device context.but does not destroy the device context handles (hDCs) temporarily associated with the CDC objects.

Windows SDK中GDI系列的函数操作HDC,而CDC对这些函数做了封装,CDC有个成员变量就是HDC m_hdc,因此CDC*的操作与HDC系列的操作是对等的,查一下微软的文档就能找对应关系。需要调用哪些CDC的函数,是否要Release, 甚至是DeleteDC,就看如果纯用HDC的时候该怎么做。过CDC::GetSafeHdc来获得m_hdc,用GDI系列的函数操作,这两者可以互换。

具体怎么做要看程序里的逻辑关系,查一下文档中的要求,不能一概而论。
CabinLS 2011-10-07
  • 打赏
  • 举报
回复
firedtoad
这个机器人还没拖走?
Roy_Smiling 2011-10-06
  • 打赏
  • 举报
回复
不懂dc得路过~帮顶~
caddor2011 2011-10-06
  • 打赏
  • 举报
回复
红色的那段话,是根据网上总结的,但是未必就对


看以下的一个例子, 给一个ListBox 添加右键:


POINT curpoint;
GetCursorPos(&curpoint);
ScreenToClient(&curpoint);

RECT test;
int i = 0;

while(i<= GetCount())
{
GetItemRect(i, &test);

if (curpoint.y < test.bottom)
{
// 将当前右击项选中
SetCurSel(i);

// 加载弹出菜单
CMenu temp,*ptr;
temp.LoadMenu(IDR_LISTBOX_MENU);
ptr = temp.GetSubMenu(0);
ClientToScreen(&point);
ptr->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y, GetParent());

break;
}
else
// 若之前选中了某项,而现在的右击又没有击中选项,则取消之前的选项
SetCurSel(-1);

i++;
}

CListBox::OnRButtonDown(nFlags, point);



menu 也是局部变量, 也没有Detach() !!! 可是依然可以正常用,毫无问题。。。。

不知道是怎么回事, 到底Detach是不是必须的????



[Quote=引用 4 楼 caddor2011 的回复:]
CDC::FromHandle 是静态函数,参数是句柄,根据句柄返回一个CDC的指针,

指着一个对象,这个对象是临时的,但是生命期很长,否则按照 c++的语法来说,

返回一个临时对象的指针或引用,肯定有问题。。。

通过给以上这些对象赋予句柄,你可以发现MFC的对象的封装操作是通过调用一个静态的成员函数 FromHandle来实现的。举例,已知一个值为hWnd的HWND

CW……
[/Quote]
caddor2011 2011-10-06
  • 打赏
  • 举报
回复
CDC::FromHandle 是静态函数,参数是句柄,根据句柄返回一个CDC的指针,

指着一个对象,这个对象是临时的,但是生命期很长,否则按照 c++的语法来说,

返回一个临时对象的指针或引用,肯定有问题。。。

通过给以上这些对象赋予句柄,你可以发现MFC的对象的封装操作是通过调用一个静态的成员函数 FromHandle来实现的。举例,已知一个值为hWnd的HWND

CWnd::FromHandle(hWnd)

将会返回一个指向CWnd的指针,这个指针封装了hWnd。如果hWnd并没有产生一个明确的对象,那么一个临时的CWnd将被创建出来封装hWnd。这使通过任何句柄获得一个有效的C++对象变得可能。



所以用Detach来给到DC与 c++对象,

如果不隔断,那么函数一运行完毕,析构函数会强制去销毁那个资源


如果Detach后, 还是会运行析构函数,但是不会去销毁那个资源

区别在于此





chouxiaoya8100 2011-10-06
  • 打赏
  • 举报
回复
再问一个, 对于消息映射宏,比如对于WM_PAINT这个消息,如果不显式添加,那么请问,是不是这个消息响应函数,就不会被调用,,

我感觉是这样的, 想确认一下


64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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