• duilib CNotifyPump


    CNotifyPump 主要进行的是消息的映射还有相关VirtualWnd的操作

    class UILIB_API CNotifyPump
    {
    public:
        bool AddVirtualWnd(CDuiString strName,CNotifyPump* pObject);
        bool RemoveVirtualWnd(CDuiString strName);
        void NotifyPump(TNotifyUI& msg);
        bool LoopDispatch(TNotifyUI& msg);
        DUI_DECLARE_MESSAGE_MAP()
    private:
        CStdStringPtrMap m_VirtualWndMap;
    };
    View Code

    这里用的比较好的是WinImplBase,在OnNotify中调用NotifyPump,当主窗口中有虚拟窗口,并且AddVirtualWnd之后,则会在调用主窗口的OnNotify之后,要去调用父类的__super::OnNotify。具体可以看官方demo中的RichListDemo

    void CRichListWnd::Notify( TNotifyUI &msg )
    {
        return WindowImplBase::Notify(msg);
    }
    
    
    CRichListWnd::CRichListWnd(void)
    {
        m_Page1.SetPaintMagager(&m_PaintManager);
        m_Page2.SetPaintMagager(&m_PaintManager);
    
        AddVirtualWnd(_T("page1"),&m_Page1);
        AddVirtualWnd(_T("page2"),&m_Page2);
    }
    
    CRichListWnd::~CRichListWnd(void)
    {
        RemoveVirtualWnd(_T("page1"));
        RemoveVirtualWnd(_T("page2"));
    }
    View Code

    那对应的消息映射跟MFC中的消息映射差不多。

    声明中:DUI_DECLARE_MESSAGE_MAP()    

    最主要的是里面的virtual const DUI_MSGMAP* GetMessageMap() const; 是virtual函数

    所以在CNotifyPump调用GetMessageMap的时候会去调用子类的GetMessageMap

    结论:所以当使用消息映射的时候就必须继承CNotifyPump类。

    特别是使用虚拟窗口的时候,因为没有具体的control父类,所以必须也只能使用CNotifyPump来进行消息映射。

    那系统是如何知道当前的控件是属于虚拟窗口的呢?

    1、在解析xml的时候当遇到virtualwnd的属性名字,则会调用对应的

    void CControlUI::SetVirtualWnd(LPCTSTR pstrValue)
    {
        m_sVirtualWnd = pstrValue;
        m_pManager->UsedVirtualWnd(true);
    }

    然后当某个控件发生消息响应的时候在void CPaintManagerUI::SendNotify(TNotifyUI& Msg, bool bAsync /*= false*/)函数中会有该操作:

        if( m_bUsedVirtualWnd )
        {
            Msg.sVirtualWnd = Msg.pSender->GetVirtualWnd();
        }

    具体该GetVirtualWnd则可以看CControlUI的GetVirtualWnd函数,当本身的虚拟窗口的名称是空的时候则会父节点查找是否是父窗口。

    这样的一系列操作之后,当调用CNotifyPump::NotifyPump的时候则就可以判断该控件是属于哪个虚拟窗口,进而通过Loopdispatch中查找该虚拟窗口对应的消息事件,并响应对应的事件操作。

    注意:当前的主窗口要添加对应的虚拟窗口,否则在NotifyPump中即使本身是虚拟窗口也无法被找到。

    AddVirtualWnd(_T("page1"),&m_Page1);

    然后在析构的时候则需要RemoveVirtualWnd(_T("page1"));

    ================================================

    这里额外说一下tooltip,刚开始一直不知道duilib使用什么机制进行显示的

    当鼠标在某个控件上停留(WM_MOUSEHOVER)并且该控件有对应的tooltip内容,则程序会显示相应的内容。

    具体是bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes)的WM_MOUSEHOVER

                // Create tooltip information
                CDuiString sToolTip = pHover->GetToolTip();
                if( sToolTip.IsEmpty() ) return true;
                ::ZeroMemory(&m_ToolTip, sizeof(TOOLINFO));
                m_ToolTip.cbSize = sizeof(TOOLINFO);
                m_ToolTip.uFlags = TTF_IDISHWND;
                m_ToolTip.hwnd = m_hWndPaint;
                m_ToolTip.uId = (UINT_PTR) m_hWndPaint;
                m_ToolTip.hinst = m_hInstance;
                m_ToolTip.lpszText = const_cast<LPTSTR>( (LPCTSTR) sToolTip );
                m_ToolTip.rect = pHover->GetPos();
                if( m_hwndTooltip == NULL ) {
                    m_hwndTooltip = ::CreateWindowEx(0, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, m_hWndPaint, NULL, m_hInstance, NULL);
                    ::SendMessage(m_hwndTooltip, TTM_ADDTOOL, 0, (LPARAM) &m_ToolTip);
                }
                ::SendMessage( m_hwndTooltip,TTM_SETMAXTIPWIDTH,0, pHover->GetToolTipWidth());
                ::SendMessage(m_hwndTooltip, TTM_SETTOOLINFO, 0, (LPARAM) &m_ToolTip);
                ::SendMessage(m_hwndTooltip, TTM_TRACKACTIVATE, TRUE, (LPARAM) &m_ToolTip);
    View Code

    但是这里发现一个小问题,就是控件为CEditUI并且里面的内容被选中的时候,使用tooltip鼠标只有在控件的边缘才能显示出来,在编辑框的内部时候却无法显示,具体这个则是因为CEditUI内部使用了系统默认的CEdit控件。

  • 相关阅读:
    git添加文件的原理流程
    maven复制包error
    一行代码-Js简单消息弹框
    WEB-给自己所有的域名加上HTTPS
    记录-配置文件-将网站协议从 HTTP 升级为 HTTPS (基于 Nginx 配置)
    记录-Mac终端自动补全的配置(解决不能输入大写T的问题)
    记录-Navicat连接MySQL8.0出现2059错误
    记录-MySQL 修改ROOT密码
    记录-Maven的安装与配置
    简单使用TensorFlow.js在浏览器进行视频实时目标识别(基于YOLO V3)
  • 原文地址:https://www.cnblogs.com/cxiaoln/p/4421109.html
Copyright © 2020-2023  润新知