金山界面库分析(5)

来源:互联网 发布:房产网络推广方案 编辑:程序博客网 时间:2024/05/14 10:36

无窗口模式---逻辑树结构的建立


对于无窗口的模式,各种控件之间的关系需要我们自己来维护,因为我们要进行消息传递,排版布局,创建等操作时都需要沿着各种包含关系来逐个调用,这样对于窗口中的控件就形成了一个逻辑上的树形结构。我们看一下CBkPanel类,这个类的名字就表示它是一个有包含功能的类,可以有自己的子节点。这个类有一个成员CAtlList<CBkWindow *> m_lstWndChild,也就是每个CBkPanel类都有一个链表,在这个链表中存储了它的子节点控件。

那么这个链表是何时被填充的呢,我们看一下LoadChilds方法,就是在这个函数中进行的填充操作,从前面我们知道,这个函数是在用xml 初始化界面是调用的。其中对于当前节点下的所有xml子节点进行下面的处理:

CBkWindow*pNewChildWindow = _CreateBkWindowByName(pXmlChild->Value());//创建控件if(!pNewChildWindow)continue;        //创建失败,不进行后续设置pNewChildWindow->SetParent(m_hBkWnd);     //设置父节点HBKWNDpNewChildWindow->SetContainer(m_hWndContainer);   //设置容器窗口的HWNDpNewChildWindow->Load(pXmlChild);           //Load这个节点的子节点m_lstWndChild.AddTail(pNewChildWindow);     //将自己加入到父节点的链表中

在CBkPanel的OnDestroy函数中进行子节点的销毁操作

       POSITION pos= m_lstWndChild.GetHeadPosition();       while (pos!= NULL)       {            CBkWindow*pBkWndChild = m_lstWndChild.GetNext(pos);            pBkWndChild->BkSendMessage(WM_DESTROY);            deletepBkWndChild;       }       m_lstWndChild.RemoveAll();

之后进行消息传递,绘制,排版操作都可以使用这个树来进行处理,循环调用所有的节点。如在OnPaint函数中:

       POSITION pos= m_lstWndChild.GetHeadPosition();       BOOL bDisabled= IsDisabled(), bIsChildDisabled= FALSE;       while (pos!= NULL)       {            //……此处略去            pBkWndChild->BkSendMessage(WM_PAINT,(WPARAM)(HDC)dc);            //……此处略去       }

可见也是循环向每个子节点发送WM_PAINT消息。

 

同时,在界面库中,还使用了BkWnds来记录所有的控件,以便可以便捷地进行获取操作

CBkWindow类有HBKWND类型的成员变量m_hBkWnd,这是一个虚拟的窗口句柄。

BkWnds是一个控件池,创建的控件会在这里注册,并通过一个HBKWND类型变量标示,以后就可以通过控件的m_hBkWnd来获取这个控件。

原创粉丝点击