CDesktop类的开工~

CDesktop类负责处理窗口们。当一个窗口CreateWin以后,再在Window上面Add一些Control,把它Add到CDesktop里面就算完事了。当然在Add之前可以酌情保留其指针方便控制,也可以用CDesktop类的FindWindow()函数查找指定Name的Window,返回其指针再对其操作。而绘制桌面窗口的时候只需把desktop变量的指针传递给CGraph的RenderDesktop()函数即可绘画出所有的窗口及其子控件。真是方便之极。难免自己要先陶醉一下。

在CDesktop里面,我用到了STL,标准模板库。

#include <list>
using namespace std;

用了其中的list容器,来保存add函数传递来的窗口句柄。

list<CWin*> m_pWinList;

每当传进新的窗口句柄,就把他压入list容器的前面. (push_front)。

m_pWinList.push_front(pNewWin);

先规范一下窗体处理的顺序问题。
一般来说,绘画窗体是按照窗体的ZOrder循序,处于最上层的窗口最后绘画,以遮盖下层的窗口。因此定义如下规则:

1. 最前的窗口处于list容器的前端( front, begin() )
2. 处理绘画函数从list容器的后端开始逐个窗体绘画.
// 绘画所有窗口
bool CDesktop::Draw(IDirectDrawSurface * lpDDS, LPRECT lpRect)
{
 if ( m_pWinList.empty() )
  return false;

 m_pWinIterator = m_pWinList.end();

 do {
    // 遍历所有表内元素, 执行Draw
    m_pWinIterator -- ;
    (*m_pWinIterator)->Draw( lpDDS, lpRect );
 } while ( m_pWinIterator != m_pWinList.begin() );
   return true;
}
3. 处理消息函数从list容器的前端开始逐个测试传递.


因为把窗体初始化的代码单独拿了出来,所以要注意一个问题:

当切换全屏/窗口模式的时候,会释放掉旧的DirectDraw。那么旧的DirectDraw所建立的Surface同样会失效。所以,Desktop同样要在切换模式之前执行释放函数把所有的子窗体释放掉,待重新初始化DirectDraw后再重新初始化窗体。否则,窗体所保存的surface指针指向的将不会再是一个有效的DirectDrawSurface。这个问题花了我几乎一个小时去debug。得益于远程调试,两台机器并用能够一边看代码一边调试,否则切换成全屏就不能看到代码这个问题有排烦了。途中顺便也把之前提到可能的访问异常去掉了。原来CSurface没有把lpDDS初始化为NULL而使到释放宏不能判断指针的有效性,直接执行了一个无效的Release()操作。这是一个低级的错误,sigh。

好,继续完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值