duilib DirectUI库里面的一个简单的例子RichListDemo
C/C++ 4-7 964浏览 0评论1、首先来看这里的CRichListWnd 已经不再是从CWindowWnd继承了 classCRichListWnd:publicWindowImplBase 从WindowImplBase中,可以看到有三个抽象函数: virtualCDuiStringGetSkinFolder()=0; virtualCDuiStringGetSkinFile()=0; virtualLPCTSTRGetWindowClassName(void)const=0; 这些都很简单,只是返回固定的string 2、看看WindowImplBase class UILIB_API WindowImplBase : public CWindowWnd , public CNotifyPump , public INotifyUI , public IMessageFilterUI , public IDialogBuilderCallback { …… } 这个类其实也是实现了CWindowWnd、INotifyUI,即一个窗体和消息,所以他含有virtualvoidNotify(TNotifyUI&msg); 但是这里又继承了CNotifyPump,所以这里的Notify可以这么实现: void WindowImplBase::Notify(TNotifyUI& msg) { return CNotifyPump::NotifyPump(msg); } NotifyPump主要是遍历所有的虚拟窗口把消息传递出去 下面的代码列出了CRichListWnd比较重要的函数: class CRichListWnd : public WindowImplBase { public: virtual void OnFinalMessage( HWND ); virtual void Notify( TNotifyUI &msg ); virtual LRESULT OnMouseWheel( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); virtual LRESULT OnSysCommand( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ); virtual void InitWindow(); virtual LRESULT OnMouseHover( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ); virtual LRESULT OnChar( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ); DUI_DECLARE_MESSAGE_MAP() virtual void OnClick(TNotifyUI& msg); virtual void OnSelectChanged( TNotifyUI &msg ); virtual void OnItemClick( TNotifyUI &msg ); }; 因为WindowImplBase类实现了CWindowWnd中的HandleMessage,所以我们如果需要把一些重要的消息事件给重写就行; 可以看到WindowImplBase中的OnCreate(): LRESULT WindowImplBase::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { …… InitWindow(); return 0; } 所以我们需要把InitWindow给重写了 在InitWindow给每一个控件和XML的控件属性对应起来: // 初始化的事件 void CRichListWnd::InitWindow() { m_pCloseBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("closebtn"))); m_pMaxBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("maxbtn"))); m_pRestoreBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("restorebtn"))); m_pMinBtn = static_cast<CButtonUI*>(m_PaintManager.FindControl(_T("minbtn"))); } 这就完成了初始化,窗口也就起来了 这个Demo中,是使用到了虚拟页的,也就是CPage1,如果不使用,他的消息会回到CRichListWnd中被处理,但是如果CPage1中处理了消息,CRichListWnd就不做处理了 我们来看看CPage1所要处理的消息: 同样的CRichListWnd消息 当页面发生OnClick或者OnItemClick时候,已经挂上了虚拟页CPage1,那么CRichListWnd消息的就失效了 3、关于虚拟页CPage的 这样挂上虚拟页的: CRichListWnd::CRichListWnd(void) { m_Page1.SetPaintMagager(&m_PaintManager); AddVirtualWnd(_T("page1"),&m_Page1); } CRichListWnd::~CRichListWnd(void) { RemoveVirtualWnd(_T("page1")); } 看到这里有个宏(因为继承了CNotifyPump都可以这样用): DUI_BEGIN_MESSAGE_MAP(CPage1, CNotifyPump) DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK, OnClick) DUI_ON_MSGTYPE(DUI_MSGTYPE_SELECTCHANGED, OnSelectChanged) DUI_ON_MSGTYPE(DUI_MSGTYPE_ITEMCLICK, OnItemClick) DUI_END_MESSAGE_MAP() 这是整个消息映射的,表面我们关心这几个消息函数,同样的还可以在UIDefine.h中找到其他的消息类型的事件 在void CPage1::OnItemClick( TNotifyUI &msg )中原来是没有代码的,需要手动把CRichListWnd的那部分粘上去(或者去掉挂上虚拟页的部分) 之后我们点击进度条的时候,这个函数才会执行 同样的把鼠标停留 在操作按钮上面会执行函数CRichListWnd::OnMouseHover 同样的这个demo的其他部分也就这么回事了