转载请说明原出处,谢谢@@
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虚拟界面的实现说明,有什么地方没有说明,请大家纠正。
DUILIB虚拟窗口机制