对象与资源

来源:互联网 发布:国际网络应该受管制 编辑:程序博客网 时间:2024/05/16 06:20
对象与资源
还是以进度栏为例
在自定义消息中,进度栏创建完成后,还存在一些问题。
问题1:
创建完成后,当移动窗口,进度栏只能存在于固定的位置,并不能随碰着窗口大小改变而改变。
原因:
当窗口的尺寸区域发生变化的时候,那么状态栏的尺寸区域也要发生变化,
那么,最早所获取的窗格也就不准确了,所以就看到进度栏脱离了状态栏上的方格。
解决:
避免这种情况就需要在窗口发生变化时,重新去获取固定索引的区域,然后将进度栏移动到这个
区域冯冯当中。
发送WM_PAINT的消息,在这里面重新获取窗格的矩形区域,然后将其重新移动至距形区域
在CMianFrame中添加WM_PAINT消息。并添加处理函数。如下:
void CMainFrame::OnPaint(){CPaintDC dc(this); // device context for paintingCRect rect;m_wndStatusBar.GetItemRect(5,&rect);//得到所在的距形区域的大小m_progess.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH, rect , &m_wndStatusBar,111);m_progess.SetPos(50);// TODO: 在此处添加消息处理程序代码// 不为绘图消息调用 CFrameWnd::OnPaint()}

那么是不是这做就OK 了?运行之后,会发生如下错误:
图一

这是为什么?通过调试,设置断点。

在进行初始化的时候,先运行至上面。然后

又到Onpaint函数中,rect 值的变化和对象m_progres变化如下图:

然后又运行至Onprogress()函数当中,以再次调用到对象m_progress 也同时创建使用相同的资源



然后进而出如上的错误。

经过跟踪发现,生成的过程,用相同的对象即为m_progress用到了两次,并且同一对象,用到创建相同的资源,所以
会出错。
就是说必须把对象相关的资源销毁,才能重新调用 

解决方案:可以把PostMessage()注释掉,即然用到Onpaint()进行重绘,就不需要自定义消息了。



但这样已经行了吗?当生成窗口后我们拉动窗口,其大小发生变化,还是会发生如图一的错误!

其实还是一样的错误 ,当窗口发生改变时候,就会发送一个wm_paint的消息,于是就会调用Onpaint()这个消息
响应函数,因为我们已经创建进度栏,并且已经将它与CProgressCtrl对象相关联,又一次去创建,当然会发生问题。
可以在Onpaint函数 中进行判断:对象m_progress是否关联了相关的资源?
void CMainFrame::OnPaint(){CPaintDC dc(this); // device context for paintingCRect rect;m_wndStatusBar.GetItemRect(5,&rect);//得到所在的距形区域的大小if(!m_progess.m_hWnd){m_progess.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH, rect , &m_wndStatusBar,111);}elsem_progess.MoveWindow(rect);m_progess.SetPos(50);// TODO: 在此处添加消息处理程序代码// 不为绘图消息调用 CFrameWnd::OnPaint()}


原创粉丝点击