我有一个窗口类,它在右键单击时创建一个弹出菜单。
MyWnd::OnRButtonDown(/* parameters*/)
{
// do something
VERIFY(m_RightClickMenu.CreatePopupMenu());
MENUINFO MenuInfo;
m_RightClickMenu.GetMenuInfo(&MenuInfo);
MenuInfo.dwStyle = MNS_NOTIFYBYPOS;
m_RightClickMenu.SetMenuInfo(&MenuInfo);
HMENU hMenu = m_RightClickMenu.GetSafeHmenu();
if (NULL != hMenu)
{
CString tempStr;
// Add menu Items
ClientToScreen(&ptMousePos);
m_RightClickMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
TPM_HORPOSANIMATION | TPM_VERPOSANIMATION ,
ptMousePos.x, ptMousePos.y, this);
m_RightClickMenu.DestroyMenu();
}
CWnd::OnRButtonDown(nFlags, point);
}
问题是,当右键单击时,弹出菜单出现并且在用户单击任何菜单选项之前,需要关闭窗口,应用程序崩溃。
为了解决这个问题,我定义了一个函数 clear(),它发送消息以删除弹出菜单。
MyWnd::Clear()
{
if (GetSafeHwnd())
{
SendMessage(WM_CANCELMODE);
}
}
因此,首先调用 clear 然后销毁窗口。使用它,弹出菜单被删除,但应用程序仍然在 RButtonDown 函数中崩溃
m_RightClickMenu.DestroyMenu();
或者有时在
CWnd::OnRButtonDown(nFlags, point);
我认为,清除后,窗口在同一个线程中被破坏。但是 RButtonDown 中的调用被卡在单独的线程中。因此,当 RButtonDown 恢复执行时,MyWnd 类要么完全销毁,要么正在销毁。因此崩溃正在发生。
我正在考虑使用锁使其线程安全。但是如何知道我是否需要在 MyWnd 的析构函数中等待锁定尚不清楚。因为我不确定是否创建了弹出菜单。
请建议应该做什么。如何在调用 WM_CANCELMODE 或任何其他方式时停止执行 RButtonDown。
EIDT:我的 m_RightClickMenu 是 CMenu 类型