UIMenu一些修改:
UIMenu.h
CControlUI* getHover()const{ return m_pHover; }
void setHover(CControlUI* pHover){ m_pHover = pHover; }
CControlUI* m_pHover; //用来记录当前菜单属于谁弹出
UIMenu.cpp
m_pHover(nullptr) //初始化
BOOL CMenuWnd::Receive(ContextMenuParam param)
{
.....
OnClose();
m_pHover = nullptr;//窗体销毁将赋值空
....
}
case WM_KILLFOCUS:
case WM_MOUSELEAVE: //移除窗体外,自动删除
lRes = OnKillFocus(uMsg, wParam, lParam, bHandled);
实现:
HoverMenu* m_pHoverMenu;
LRESULT CMainFrame::OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
CControlUI* pHover = m_PaintManager.FindControl(pt);
auto pMenu = m_pHoverMenu->getMenu();
bool bCreateMenu = false;
CDuiPoint point;
if (pMenu&&pHover != pMenu->getHover())
{
if (pMenu->getHover())//菜单窗体还在 现在需要手动销毁窗体
{
ContextMenuParam param;
param.wParam = 1;
pMenu->Receive(param);//销毁菜单窗体 还不能delete
}
m_pHoverMenu->deleteMenu(m_pHoverMenu->getNextMenu());//删除下一个菜单对象
pMenu = m_pHoverMenu->createMenu();//刚刚销毁窗体的菜单对象现在又是pMenu的下一个
RECT rect = pHover->GetPos();
point.x = rect.left;
point.y = rect.bottom;
ClientToScreen(m_PaintManager.GetPaintWindow(), &point);
bCreateMenu = true;
}
if (bCreateMenu)
{
DuiLib::CDuiString menuxml;
if (pHover == m_pMenuTest)
{
menuxml = _T("MenuTest.xml");
}
if (!menuxml.IsEmpty())
{
pMenu->Init(NULL, menuxml.GetData(), point, &m_PaintManager, &m_pMenuCheckInfo);
pMenu->ResizeMenu();
pMenu->setHover(pHover);
}
}
bHandled = FALSE;
return 0;
}
HoverMenu.h
using namespace DuiLib;
typedef struct _node
{
DuiLib::CMenuWnd* pMenu;
_node* next;
}Node;
/*
* 两个节点的循环链表
* 鼠标悬浮控件的菜单在WM_MOUSEHOVER消息创建和销毁
* 手动销毁窗体的时候不能立即delete对象,所以需要new一个菜单对象
* 在使用另外一个节点的时候 首先delete菜单对象,因为此时窗体早已自动销毁或者该菜单还没有创建过窗体
*/
class HoverMenu
{
public:
HoverMenu();
~HoverMenu();
DuiLib::CMenuWnd* getMenu();
DuiLib::CMenuWnd* getNextMenu();
void deleteMenu(DuiLib::CMenuWnd* pMenu);
DuiLib::CMenuWnd* createMenu();
void Clear();
private:
Node* m_pNode;
};
HoverMenu.cpp
HoverMenu::HoverMenu()
{
m_pNode = new Node;
m_pNode->pMenu = new DuiLib::CMenuWnd;
auto pnode = new Node;
pnode->pMenu = new DuiLib::CMenuWnd;
m_pNode->next = pnode;
pnode->next = m_pNode;
}
HoverMenu::~HoverMenu()
{
}
DuiLib::CMenuWnd* HoverMenu::getMenu()
{
return m_pNode->pMenu;
}
DuiLib::CMenuWnd* HoverMenu::getNextMenu()
{
DuiLib::CMenuWnd* pMemu = nullptr;
if (m_pNode&&m_pNode->next)
{
pMemu = m_pNode->next->pMenu;
m_pNode = m_pNode->next;
}
return pMemu;
}
void HoverMenu::deleteMenu(DuiLib::CMenuWnd* pMenu)
{
if (m_pNode->pMenu == pMenu&&pMenu != nullptr)
{
m_pNode = m_pNode->next;
m_pNode->next->pMenu = nullptr;
delete pMenu;
}
else if (pMenu)
{
delete pMenu;
}
}
DuiLib::CMenuWnd* HoverMenu::createMenu()
{
DuiLib::CMenuWnd* pMemu = nullptr;
if (m_pNode->next&&m_pNode->next->pMenu == nullptr)
{
m_pNode = m_pNode->next;
pMemu = m_pNode->pMenu = new DuiLib::CMenuWnd;
}
return pMemu;
}
void HoverMenu::Clear()
{
if (m_pNode)
{
if (m_pNode->pMenu)
{
delete m_pNode->pMenu;
m_pNode->pMenu = nullptr;
}
auto pnode = m_pNode->next;
delete m_pNode;
m_pNode = nullptr;
if (pnode)
{
if (pnode->pMenu)
{
delete pnode->pMenu;
}
delete pnode;
}
}
}