一、做一个duilib公共头文件
#pragma once #include <UIlib.h> using namespace DuiLib; #ifdef _DEBUG # ifdef _UNICODE # pragma comment(lib, "DuiLib_ud.lib") # else # pragma comment(lib, "DuiLib_d.lib") # endif #else # ifdef _UNICODE # pragma comment(lib, "DuiLib_u.lib") # else # pragma comment(lib, "DuiLib.lib") # endif #endif // 以XML生成界面的窗口基类 class CXMLWnd : public WindowImplBase { public: explicit CXMLWnd(LPCTSTR pszXMLPath) : m_strXMLPath(pszXMLPath) {} public: virtual LPCTSTR GetWindowClassName() const { return _T("XMLWnd"); } virtual CDuiString GetSkinFile() { return m_strXMLPath; } virtual CDuiString GetSkinFolder() { return _T(""); } protected: CDuiString m_strXMLPath; }; // 将HWND显示到CControlUI上面 class CWndUI: public CControlUI { public: CWndUI(): m_hWnd(NULL){} virtual void SetInternVisible(bool bVisible = true) { __super::SetInternVisible(bVisible); ::ShowWindow(m_hWnd, bVisible); } virtual void SetPos(RECT rc, bool bNeedInvalidate) { __super::SetPos(rc, bNeedInvalidate); ::SetWindowPos(m_hWnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOACTIVATE); } BOOL Attach(HWND hWndNew) { if (! ::IsWindow(hWndNew)) { return FALSE; } m_hWnd = hWndNew; return TRUE; } HWND Detach() { HWND hWnd = m_hWnd; m_hWnd = NULL; return hWnd; } protected: HWND m_hWnd; };
头文件DuiFrameWnd.h
#pragma once #include "duilib.h" #include "MyDlg.h" #include "resource.h" class CDuiFrameWnd : public CXMLWnd { public: explicit CDuiFrameWnd(const CString& strXmlPath, CMyDlg* pDlgMain = NULL); ~CDuiFrameWnd(); private: virtual void Notify(TNotifyUI& msg); virtual void OnFinalMessage(HWND hWnd); virtual CControlUI* CreateControl(LPCTSTR pstrClassName); virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); protected: CMyDlg* m_pDlgMain; // 主对话框,所有的消息处理都交给他 vector<CWnd *> m_btn; // 收集所有的指针,方便最后销毁 };
#include "stdafx.h" #include "DuiFrameWnd.h" #define IDC_BUTTON_DUI_NEXT 2000 CDuiFrameWnd::CDuiFrameWnd(const CString& strXmlPath, CMyDlg* pDlgMain) : CXMLWnd(strXmlPath),m_pDlgMain(pDlgMain) { CPaintManagerUI::SetInstance(AfxGetInstanceHandle()); // 指定duilib的实例 CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath()); // 指定duilib资源的路径,这里指定为和exe同目录 } CDuiFrameWnd::~CDuiFrameWnd() {} void CDuiFrameWnd::OnFinalMessage(HWND hWnd) { if (!m_btn.empty()) { for (auto* e : m_btn) { if (e != NULL) { delete e; e = NULL; } } } delete this; } void CDuiFrameWnd::Notify(TNotifyUI& msg) { if (msg.sType == _T("click")) { if (msg.pSender->GetName() == _T("btn")) { if (m_pDlgMain != NULL) { /*转移到m_pDlgMain中处理*/ } } } __super::Notify(msg); } CControlUI* CDuiFrameWnd::CreateControl(LPCTSTR pstrClassName) { if (_tcsicmp(pstrClassName, _T("Wnd")) == 0) { CWndUI *pUI = new CWndUI; CButton * btn = new CButton; btn->Create(_T("MFC"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, CRect(0, 0, 0,0), CWnd::FromHandle(m_PaintManager.GetPaintWindow()), IDC_BUTTON_DUI_NEXT); pUI->Attach(btn->GetSafeHwnd()); m_btn.push_back(btn); return pUI; } else if (_tcsicmp(pstrClassName, _T("Dialog")) == 0) { CWndUI *pUI = new CWndUI; CMyDlg* m_pDlg = new CMyDlg; m_pDlg->Create(IDD_DIALOG1); pUI->Attach(m_pDlg->GetSafeHwnd()); m_pDlgMain = m_pDlg; m_btn.push_back(m_pDlgMain); return pUI; } return NULL; } LRESULT CDuiFrameWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_COMMAND: { if (IDC_BUTTON_DUI_NEXT == wParam) { if (m_pDlgMain != NULL) { /*转移到m_pDlgMain中处理*/ } } break; } default: break; } return __super::HandleMessage(uMsg, wParam, lParam); }三、在MFC中的app里初始化duilib对话框
CDuiFrameWnd *pFrame = new CDuiFrameWnd(_T("skin.xml")); m_pMainWnd = CWnd::FromHandle(*pFrame); pFrame->Create(NULL, _T("DUIWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE); pFrame->CenterWindow(); INT_PTR nResponse = pFrame->ShowModal();