先上效果图
1、对需要响应的按钮新建一个基于duilib实现的类
如:
if (msg.sType == _T("click"))
{
if (msg.pSender == m_pBtSetting)
{
new CSettingUI(m_hWnd, m_pBtSetting, m_wcurpath, m_iconfilepath);
}
}
2、重写基于duilib的类
#pragma once
#include "stdafx.h"
class CSettingUI : public WindowImplBase
{
public:
CSettingUI(HWND hParent, CControlUI *pControl, wstring curpath, string iconfilepath) {
m_hParent = hParent;
Create(NULL, _T("SettingUI"), WS_POPUP | WS_VISIBLE, WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST);
};
public:
CDuiString GetSkinFolder() { return _T(""); }
CDuiString GetSkinFile(){ return _T(""); }
void Init()
{
if (m_pControl == NULL) return;
RECT rcConrol = m_pControl->GetPos();
SIZE szWnd = m_pm.GetInitSize();
POINT ptWnd = { 0 };
ptWnd.x = rcConrol.right - szWnd.cx;
ptWnd.y = rcConrol.bottom;
::ClientToScreen(m_hParent, &ptWnd);
//设置新窗体的位置
SetWindowPos(m_hWnd, NULL, ptWnd.x, ptWnd.y, szWnd.cx, szWnd.cy, SWP_NOSIZE | SWP_NOACTIVATE);
}
public:
LPCTSTR GetWindowClassName() const { return _T("SettingUI"); };
UINT GetClassStyle() const { return CS_DBLCLKS; };
void OnFinalMessage(HWND /*hWnd*/) { delete this; };
void Notify(TNotifyUI& msg)
{
if (msg.sType == _T("click"))
{
}
}
void OnLClick(CControlUI *pControl)
{
}
//因为我主界面使用的zip包,所以这里我是重写的创建界面函数
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
styleValue &= ~WS_CAPTION;
::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
m_pm.Init(m_hWnd);
CDialogBuilder builder;
//加载界面资源的xml
CControlUI* pRoot = builder.Create(_T("Setting.xml"), (UINT)0, this, &m_pm);
ASSERT(pRoot && "Failed to parse XML");
m_pm.AttachDialog(pRoot);
m_pm.AddNotifier(this);
SetClassLong(m_hWnd, GCL_STYLE, GetClassLong(m_hWnd, GCL_STYLE) | CS_DROPSHADOW);
Init();
return 0;
}
LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
return 0;
}
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
bHandled = FALSE;
return 0;
}
LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (::IsIconic(*this)) bHandled = FALSE;
return (wParam == 0) ? TRUE : FALSE;
}
LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return 0;
}
LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return 0;
}
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lRes = 0;
BOOL bHandled = TRUE;
switch (uMsg) {
case WM_CREATE: lRes = OnCreate(uMsg, wParam, lParam, bHandled); break;
case WM_CLOSE: lRes = OnClose(uMsg, wParam, lParam, bHandled); break;
case WM_DESTROY: lRes = OnDestroy(uMsg, wParam, lParam, bHandled); break;
case WM_NCACTIVATE: lRes = OnNcActivate(uMsg, wParam, lParam, bHandled); break;
case WM_NCCALCSIZE: lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled); break;
case WM_NCPAINT: lRes = OnNcPaint(uMsg, wParam, lParam, bHandled); break;
case WM_KILLFOCUS: lRes = OnKillFocus(uMsg, wParam, lParam, bHandled); break;
default:
bHandled = FALSE;
}
if (bHandled) return lRes;
if (m_pm.MessageHandler(uMsg, wParam, lParam, lRes)) return lRes;
return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
}
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
Close(0);
return 0;
}
public:
CPaintManagerUI m_pm;
std::wstring m_wcurpath;
private:
HWND m_hParent;
CControlUI* m_pControl;
};
到此,就完成了!!!新界面有单独的事件响应啥的,也可以和主界面进行联动,总之就是很灵活。