您的位置:首页 > 其它

对象与资源

2013-05-02 22:17 92 查看
对象与资源
还是以进度栏为例
在自定义消息中,进度栏创建完成后,还存在一些问题。
问题1:
创建完成后,当移动窗口,进度栏只能存在于固定的位置,并不能随碰着窗口大小改变而改变。
原因:
当窗口的尺寸区域发生变化的时候,那么状态栏的尺寸区域也要发生变化,
那么,最早所获取的窗格也就不准确了,所以就看到进度栏脱离了状态栏上的方格。
解决:
避免这种情况就需要在窗口发生变化时,重新去获取固定索引的区域,然后将进度栏移动到这个
区域冯冯当中。
发送WM_PAINT的消息,在这里面重新获取窗格的矩形区域,然后将其重新移动至距形区域
在CMianFrame中添加WM_PAINT消息。并添加处理函数。如下:
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting

CRect 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 painting

CRect rect;
m_wndStatusBar.GetItemRect(5,&rect);//得到所在的距形区域的大小

if(!m_progess.m_hWnd)
{
m_progess.Create(WS_CHILD|WS_VISIBLE|PBS_SMOOTH, rect ,
&m_wndStatusBar,111);
}
else
m_progess.MoveWindow(rect);
m_progess.SetPos(50);
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CFrameWnd::OnPaint()
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: