Здравствуйте. Пытаюсь сделать себе уй на основе мфс, есть несколько вопросов по поводу динамического создания контекстного меню.
Есть такой код, он рабочий, таблица динамически обновляющихся значений CListView вставлен в CFrame :
Код:
#include "stdafx.h"
#include "MyFrame.h"
#include "MainWindow.h"
#include "resource.h"
IMPLEMENT_DYNCREATE(MyFrame, CFrameWnd)
MyFrame::MyFrame(CMainWindow* pParent, int i) : CFrameWnd(), p_mainWindow(pParent), index(i)
{
m_startStop = true;
}
MyFrame::~MyFrame)
{
}
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_GETMINMAXINFO()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_NOTIFY(NM_RCLICK, 133, OnRButtonClick)
ON_COMMAND_RANGE(321, 322, StartStop)
END_MESSAGE_MAP()
...............
int MyFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
HINSTANCE hInst = AfxGetInstanceHandle();
HICON m_hIconSmall = (HICON) ::LoadImage(hInst, MAKEINTRESOURCE(IDI_RAW_BBO),
IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
HICON m_hIconBig = (HICON) ::LoadImage(hInst, MAKEINTRESOURCE(IDI_RAW_BBO),
IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
SetIcon(m_hIconSmall, false);
SetIcon(m_hIconBig, true);
CRect rect;
GetClientRect(&rect);
m_listCtrl.Create(LVS_ICON|LVS_REPORT|WS_VISIBLE, rect, this, 133);
m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
SetTimer(1, 200, 0);
return 0;
}
............
..........
void MyFrame::OnRButtonClick(NMHDR* pNMHDR, LRESULT* pResult)
{
POINT point;
GetCursorPos(&point);
CMenu menu;
menu.CreatePopupMenu();
if (m_startStop)
menu.AppendMenu(MF_STRING, 322, "Stop");
else
menu.AppendMenu(MF_STRING, 321, "Start");
menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, point.x, point.y, this);
}
void MyFrame::StartStop(UINT nID)
{
if (nID == 321)
{
SetTimer(1, 200, 0);
m_startStop = true;
}
else
{
KillTimer(1);
m_startStop = false;
}
}
Создается, в простейшем случае менюшка с одной строкой, либо start, либо stop.
Если поменять CListView на CView, надо еще окошко сделать для визуализации графика функции, то меню не создается, вообще нет реакции на RBnClick
Пробовал процедуру создания меню вынести в реализацию CChildView:
Код:
#include "stdafx.h"
#include "ChildView.h"
#include ".\childview.h"
CChildView::CChildView()
{
m_startStop = true;
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_NOTIFY(NM_RCLICK, AFX_IDW_PANE_FIRST, OnRButtonClick)
ON_COMMAND_RANGE(321, 322, StartStop)
END_MESSAGE_MAP()
...............
void CChildView::OnRButtonClick(NMHDR* pNMHDR, LRESULT* pResult)
{
POINT point;
ClientToScreen(&point);
p_menu = new CMenu;
p_menu->CreatePopupMenu();
if (m_startStop)
menu->AppendMenu(MF_STRING, 322, "Stop");
else
menu->AppendMenu(MF_STRING, 321, "Start");
menu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, point.x, point.y, this);
TRACE0("R Button Pressed\n");
}
void CChildView::StartStop(UINT nID)
{
if (nID == 321)
{
//SetTimer(1, 200, 0);
m_startStop = true;
}
else
{
//KillTimer(1);
m_startStop = false;
}
}
Тоже не работает.
Заработало только таким способом;
Код:
#include "stdafx.h"
#include "ChildView.h"
#include ".\childview.h"
CChildView::CChildView()
{
m_startStop = true;
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_NOTIFY_REFLECT(NM_RCLICK, OnRButtonClick)
ON_WM_CONTEXTMENU()
ON_COMMAND_RANGE(321, 322, StartStop)
END_MESSAGE_MAP()
............
..........
void CChildView::OnRButtonClick(NMHDR* pNMHDR, LRESULT* pResult)
{
TRACE0("OnRButtonClick()\n");
SendMessage(WM_CONTEXTMENU, (WPARAM) m_hWnd, GetMessagePos());
*pResult = 1;
}
void CChildView::StartStop(UINT nID)
{
if (nID == 321)
{
m_startStop = true;
}
else
{
m_startStop = false;
}
}
void CChildView::OnContextMenu(CWnd* pWnd, CPoint ptMousePos)
{
if (ptMousePos.x == -1 && ptMousePos.y == -1)
ptMousePos = (CPoint) GetMessagePos();
ScreenToClient(&ptMousePos);
ClientToScreen(&ptMousePos);
CMenu menu ;
menu.CreatePopupMenu();
if (m_startStop)
menu.AppendMenu(MF_STRING, 322, "Stop");
else
menu.AppendMenu(MF_STRING, 321, "Start");
menu.TrackPopupMenu( TPM_LEFTALIGN|TPM_LEFTBUTTON, ptMousePos.x, ptMousePos.y, this );
}
А почему так?
И еще вопрос, каждый раз создавать новое меню в OnContextMenu или в OnRButtonClick наверно не кошерно, надо вынести
p_menu = new CMenu;
p_menu->CreatePopupMenu();
куда то в OnCreate().
Как тогда избавиться от лишних строчек, которые будут бесконечно добавляться при каждом вызове меню?
И надо ли добавить к классу CChildView
OnDestroy()
{
delete p_menu;
}??