策略为王源代码分析-鼠标右键弹出框

Published

第一部分 初始化弹出框菜单

G:\stock\TskingVS2019\src\Client\StkUI\MainFrm.cpp

定义了弹出框菜单消息ON_WM_INITMENUPOPUP()

BEGIN_MESSAGE_MAP(CMainFrame, CTskMainFrame)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_WM_SIZE()
	ON_WM_CLOSE()
	ON_WM_INITMENUPOPUP()  //鼠标右键弹出框菜单
        ....
END_MESSAGE_MAP() 

 

定义ON_WM_INITMENUPOPUP()消息的处理函数OnInitMenuPopup()

//ON_WM_INITMENUPOPUP( )消息的处理函数
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
	if (!bSysMenu && pPopupMenu)
	{
		InitMenuPopup(pPopupMenu);
	}

	CTskMainFrame::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
}

在InitMenuPopup(CMenu* pPopupMenu)函数中,判断当前是哪个视图界面,然后加载不同的弹出菜单项。

//右键弹出菜单初始化 by freeman
void CMainFrame::InitMenuPopup(CMenu* pPopupMenu)
{
	if (NULL == pPopupMenu || NULL == pPopupMenu->GetSafeHmenu())
		return;

	for (UINT nMenu = 0; nMenu < pPopupMenu->GetMenuItemCount(); nMenu++)
	{
		if (ID_SLIST_GROUP1 == pPopupMenu->GetMenuItemID(nMenu))
		{
			pPopupMenu->ModifyMenu(nMenu, MF_BYPOSITION | MF_GRAYED, ID_SLIST_GROUP1, (LPCTSTR)NULL);
			for (UINT k = pPopupMenu->GetMenuItemCount() - 1; k > nMenu; k--)
				pPopupMenu->DeleteMenu(k, MF_BYPOSITION);
			AfxMenuInsertGroup(pPopupMenu, nMenu + 1, ID_SLIST_GROUP_START, ID_SLIST_GROUP_END, TRUE);
			break;
		}
		else if (ID_SLIST_DOMAIN1 == pPopupMenu->GetMenuItemID(nMenu))
		{
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);
			AfxMenuInsertDomain(pPopupMenu, nMenu, ID_SLIST_DOMAIN_START, ID_SLIST_DOMAIN_END);
			break;
		}
		else if (ID_OPTION_ADDTOGROUP == pPopupMenu->GetMenuItemID(nMenu))
		{
			pPopupMenu->ModifyMenu(nMenu, MF_BYPOSITION | MF_GRAYED, ID_OPTION_ADDTOGROUP, (LPCTSTR)NULL);
			for (UINT k = pPopupMenu->GetMenuItemCount() - 1; k > nMenu; k--)
				pPopupMenu->DeleteMenu(k, MF_BYPOSITION);
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			AfxMenuInsertGroup(pPopupMenu, nMenu + 1, ID_OPTION_ADDTOGROUP_START, ID_OPTION_ADDTOGROUP_END,
				pView && (pView->IsKindOf(RUNTIME_CLASS(CSListView)) || pView->IsKindOf(RUNTIME_CLASS(CGraphView)) || pView->IsKindOf(RUNTIME_CLASS(CBaseView))));
			break;
		}
		else if (ID_VIEW_TECHKLINE == pPopupMenu->GetMenuItemID(nMenu)) //日K线图右键弹出框,指标显示的子菜单 定义
		{
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			UINT	nFlags = ((pView && pView->IsKindOf(RUNTIME_CLASS(CGraphView))) ? MF_BYPOSITION | MF_STRING : MF_BYPOSITION | MF_STRING | MF_GRAYED);
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);
			for (UINT nID = STT_KLINE_MAX; nID >= STT_KLINE_MIN; nID--)  //加载右键弹出框子菜单 项目 ,其中有DJ 指标  日K线加载技术指标 by freeman
			{
				UINT	nFlagsLocal = nFlags;
				if (AfxGetProfile().IsGraphTechShow(nID))	nFlagsLocal |= MF_CHECKED;
				pPopupMenu->InsertMenu(nMenu, nFlagsLocal, ID_VIEW_TECH_START + nID, AfxGetSTTFullName(nID));
			}
		}
		else if (ID_VIEW_TECHTREND == pPopupMenu->GetMenuItemID(nMenu))
		{
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			UINT	nFlags = ((pView && pView->IsKindOf(RUNTIME_CLASS(CGraphView))) ? MF_BYPOSITION | MF_STRING : MF_BYPOSITION | MF_STRING | MF_GRAYED);
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);
			for (UINT nID = STT_TREND_MAX; nID >= STT_TREND_MIN; nID--)
			{
				UINT	nFlagsLocal = nFlags;
				if (AfxGetProfile().IsGraphTechShow(nID))	nFlagsLocal |= MF_CHECKED;
				pPopupMenu->InsertMenu(nMenu, nFlagsLocal, ID_VIEW_TECH_START + nID, AfxGetSTTFullName(nID));
			}
		}
		else if (ID_VIEW_TECHENERGY == pPopupMenu->GetMenuItemID(nMenu))
		{
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			UINT	nFlags = ((pView && pView->IsKindOf(RUNTIME_CLASS(CGraphView))) ? MF_BYPOSITION | MF_STRING : MF_BYPOSITION | MF_STRING | MF_GRAYED);
			for (UINT nID = STT_ENERGY_MAX; nID >= STT_ENERGY_MIN; nID--)
			{
				UINT	nFlagsLocal = nFlags;
				if (AfxGetProfile().IsGraphTechShow(nID))	nFlagsLocal |= MF_CHECKED;
				pPopupMenu->InsertMenu(nMenu, nFlagsLocal, ID_VIEW_TECH_START + nID, AfxGetSTTFullName(nID));
			}
		}
		else if (ID_VIEW_TECHSWING == pPopupMenu->GetMenuItemID(nMenu))
		{
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			UINT	nFlags = ((pView && pView->IsKindOf(RUNTIME_CLASS(CGraphView))) ? MF_BYPOSITION | MF_STRING : MF_BYPOSITION | MF_STRING | MF_GRAYED);
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);
			for (UINT nID = STT_SWING_MAX; nID >= STT_SWING_MIN; nID--)
			{
				UINT	nFlagsLocal = nFlags;
				if (AfxGetProfile().IsGraphTechShow(nID))	nFlagsLocal |= MF_CHECKED;
				pPopupMenu->InsertMenu(nMenu, nFlagsLocal, ID_VIEW_TECH_START + nID, AfxGetSTTFullName(nID));
			}
		}
		else if (ID_VIEW_TECHOTHER == pPopupMenu->GetMenuItemID(nMenu))
		{
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			UINT	nFlags = ((pView && pView->IsKindOf(RUNTIME_CLASS(CGraphView))) ? MF_BYPOSITION | MF_STRING : MF_BYPOSITION | MF_STRING | MF_GRAYED);
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);
			for (UINT nID = STT_OTHER_MAX; nID >= STT_OTHER_MIN; nID--)
			{
				UINT	nFlagsLocal = nFlags;
				if (AfxGetProfile().IsGraphTechShow(nID))	nFlagsLocal |= MF_CHECKED;
				pPopupMenu->InsertMenu(nMenu, nFlagsLocal, ID_VIEW_TECH_START + nID, AfxGetSTTFullName(nID));
			}
		}
		else if (ID_VIEW_TECHCLK == pPopupMenu->GetMenuItemID(nMenu)) //日K线策略为王指标加载处、右键弹出菜单初始化
		{
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			UINT	nFlags = ((pView && pView->IsKindOf(RUNTIME_CLASS(CGraphView))) ? MF_BYPOSITION | MF_STRING : MF_BYPOSITION | MF_STRING | MF_GRAYED);
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);
			for (UINT nID = STT_CLK_MAX; nID >= STT_CLK_MIN; nID--)
			{
				UINT	nFlagsLocal = nFlags;
				if (AfxGetProfile().IsGraphTechShow(nID))	nFlagsLocal |= MF_CHECKED;
				pPopupMenu->InsertMenu(nMenu, nFlagsLocal, ID_VIEW_TECH_START + nID, AfxGetSTTFullName(nID));
			}
		}
		else if (ID_VIEW_TECHUSER == pPopupMenu->GetMenuItemID(nMenu))
		{
			CView* pView = AfxGetStaticDoc()->GetActiveView();
			UINT	nFlags = ((pView && pView->IsKindOf(RUNTIME_CLASS(CGraphView))) ? MF_BYPOSITION | MF_STRING : MF_BYPOSITION | MF_STRING | MF_GRAYED);
			pPopupMenu->DeleteMenu(nMenu, MF_BYPOSITION);

			UINT nTechUserCount = CTechUser::GetTechUserCount();
			UINT nIDEnd = STT_USER_MIN + nTechUserCount - 1;
			if (nIDEnd > STT_USER_MIN + 14)
				nIDEnd = STT_USER_MIN + 14;
			for (UINT nID = nIDEnd; nID >= STT_USER_MIN; nID--)
			{
				UINT	nFlagsLocal = nFlags;
				if (AfxGetProfile().IsGraphTechShow(nID))	nFlagsLocal |= MF_CHECKED;
				pPopupMenu->InsertMenu(nMenu, nFlagsLocal, ID_VIEW_TECH_START + nID - STT_USER_MIN + 1 + STT_MAX, AfxGetSTTFullName(nID));
			}
		}
	}
}

通过查找 包含WM_RBUTTONDOWN 的源码,我们发现:

1.在G:\stock\TskingVS2019\src\Client\StkUI\ChildFrm.cpp文件中,有一个BOOL CChildFrame::PreTranslateMessage(MSG* pMsg) 中,定义了按下鼠标右键时,弹出那个菜单框。

BOOL CChildFrame::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	CMainFrame * pMainFrame = AfxGetMainFrame( );
	if( WM_SYSKEYDOWN == pMsg->message
		|| WM_SYSKEYUP == pMsg->message 
		|| WM_SYSCHAR == pMsg->message )
	{
		if( pMainFrame && VK_F4 == pMsg->wParam )
		{
			pMainFrame->PostMessage( WM_CLOSE );
			return TRUE;
		}
	}
	else if( WM_RBUTTONUP == pMsg->message
		|| WM_RBUTTONDOWN == pMsg->message
		|| WM_NCRBUTTONUP == pMsg->message
		|| WM_NCRBUTTONDOWN == pMsg->message )
	{
		CWnd* pWnd = CWnd::FromHandlePermanent(pMsg->hwnd);
		CView * pView = DYNAMIC_DOWNCAST( CView, pWnd );
		if( NULL == pView )
			pView = GetActiveView();
		
		/*根据各种的视图定义其对应的菜单弹出框ID 2019/06/08 by freeman
		*菜单项目在StkUI.rc->Menu中定义
		*/
		UINT	nMenuID	=	0;
		if( pView && pView->IsKindOf(RUNTIME_CLASS(CWizardView)) )
			nMenuID	=	IDR_POPUP_WIZARDVIEW;
		else if( pView && pView->IsKindOf(RUNTIME_CLASS(CSimuView)) )
			nMenuID	=	IDR_POPUP_SIMUVIEW;
		else if( pView && pView->IsKindOf(RUNTIME_CLASS(CSListView)) ) //如:在股票列表窗口点击鼠标右键时,弹出框菜单ID=IDR_POPUP_SLISTVIEW 2019/06/08 by freeman
			nMenuID	=	IDR_POPUP_SLISTVIEW;

 

根据各种的视图定义其对应的菜单弹出框ID 2019/06/08 by freeman
菜单项目在StkUI.rc->Menu中定义
如:在股票列表窗口点击鼠标右键时,视图文件是SListView.cpp,弹出框菜单ID=IDR_POPUP_SLISTVIEW