首页 > 代码库 > DUILIB虚拟窗口机制

DUILIB虚拟窗口机制

转载请说明原出处,谢谢@@


Duilib虚拟界面由CNotifyPump类控制。
CNotifyPump类提供了AddVirtualWnd方法,

按虚拟窗口名称为Key值,绑定CNotifyPump类型的虚拟窗口添加到虚拟窗口m_VirtualWndMap容器中。

看下方红色代码:

boolCNotifyPump::AddVirtualWnd(CDuiString strName,CNotifyPump* pObject)
{
                   if( m_VirtualWndMap.Find(strName) == NULL )
                   {
                                      m_VirtualWndMap.Insert(strName.GetData(),(LPVOID)pObject);
                                      return true;
                   }
                   return false;
}
提供了NotifyPump方法:遍历虚拟窗口处理消息。
看下方红色代码:

void CNotifyPump::NotifyPump(TNotifyUI& msg)
{
             ///遍历虚拟窗口
               if(!msg.sVirtualWnd.IsEmpty() )
              {
                         for( int i= 0; i< m_VirtualWndMap.GetSize(); i++ ) 
                        {
                                if(LPCTSTR key = m_VirtualWndMap.GetAt(i) )
                                {
                                       if(_tcsicmp(key, msg.sVirtualWnd.GetData()) == 0 )
                                       {
                                               CNotifyPump* pObject = static_cast<CNotifyPump*>(m_VirtualWndMap.Find(key,false));
                                                if(pObject && pObject->LoopDispatch(msg) )
                                                                   return;
                                        }
                                  }
                         }
                   }

                   //遍历主窗口
                   LoopDispatch( msg );
}
如何跟虚拟窗口绑定关系?
控件提供设置虚拟窗口的属性“virtualwnd”,
设置虚拟窗口名称方法和设置使用虚拟窗口标志。

void CControlUI::SetVirtualWnd(LPCTSTR pstrValue)
{
m_sVirtualWnd = pstrValue;
m_pManager->UsedVirtualWnd(true);
}
获取虚拟窗口名称方法:
CDuiString CControlUI::GetVirtualWnd() const
{
CDuiString str;
if( !m_sVirtualWnd.IsEmpty() ){
str = m_sVirtualWnd;
}
else{
CControlUI* pParent = GetParent();
if( pParent != NULL){
str = pParent->GetVirtualWnd();
}
else{
str = _T("");
}
}
return str;
}
return str;
}
控件在发送消息时候,当使用虚拟窗口标志m_bUsedVirtualWnd 有效是,带上虚拟窗口名称信息一起发出。
看下方红色代码:

void CPaintManagerUI::SendNotify(TNotifyUI& Msg, bool bAsync /*= false*/)
{
    Msg.ptMouse = m_ptLastMousePos;
    Msg.dwTimestamp = ::GetTickCount();
if( m_bUsedVirtualWnd )
{
Msg.sVirtualWnd = Msg.pSender->GetVirtualWnd();
}



    if( !bAsync ) {
        // Send to all listeners
        if( Msg.pSender != NULL ) {
            if( Msg.pSender->OnNotify ) Msg.pSender->OnNotify(&Msg);
        }
        for( int i = 0; i < m_aNotifiers.GetSize(); i++ ) {
            static_cast<INotifyUI*>(m_aNotifiers[i])->Notify(Msg);
        }
    }
    else {
        TNotifyUI *pMsg = new TNotifyUI;
        pMsg->pSender = Msg.pSender;
        pMsg->sType = Msg.sType;
        pMsg->wParam = Msg.wParam;
        pMsg->lParam = Msg.lParam;
        pMsg->ptMouse = Msg.ptMouse;
        pMsg->dwTimestamp = Msg.dwTimestamp;
        m_aAsyncNotify.Add(pMsg);
    }
}
最后消息到voidCNotifyPump::NotifyPump(TNotifyUI& msg)中的遍历虚拟窗口处理消息。


本文主要是记录下对于Duilib虚拟界面的实现说明,有什么地方没有说明,请大家纠正。