Re: CMenu from SubMenu
On Jan 19, 11:23 pm, Joseph M. Newcomer <newco...@flounder.com> wrote:
First, why are you doing OnCommand? You have asked a question of an im=
plementation detail
without once explaining what it is you are trying to achieve?
Note that there is no known way to get a menu from a submenu, or even kno=
w that a submenu
is involved. You would have to walk the entire menu tree yourself, sea=
rching for the menu
that has the ID you are looking at, and as a consequence of that recursiv=
e walk, you would
know what the parent menu is. BUt you cannot derive it from the wParam=
/lParam pair at
this point. In fact, it could have been a toolbar button that triggere=
d this.
=
joe
On Mon, 19 Jan 2009 06:20:35 -0800 (PST), Kuenga <sagku...@gmail.com> wro=
te:
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
UINT nID = LOWORD(wParam);//ID which generated the message
HWND hWndCtrl = (HWND)lParam;//control
int nCode = HIWORD(wParam);//type of message
if(nCode==0)
{
CString menuString,menuStr;
CMenu *pCMenu = GetMenu();
pCMenu->GetMenuString(LOWORD(wParam),menuStr,MF_=
BYCOMMAND);
}
return CMDIFrameWnd::OnCommand(wParam,lParam);
}
In the above code, I need to get the CMenu whose SubMenu is pCMenu. Is
there any way to get the CMenu in reverse way, i.e. from SubMenu
getting the CMenu. There is other way, getting SubMenu from CMenu but
didnot get way to do the other way round.
Joseph M. Newcomer [MVP]
email: newco...@flounder.com
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm- Hide quoted text -
- Show quoted text -
Hi Joseph,
I want to achieve record and replay of the user action. Now you will
complain why do I need to do that, I can go for the Command Design
Pattern. But that is suitable for new development but not on code
which is about ten years old and objects are tightly coupled. So I
went this way. By logging menu command and replaying it with
SendMessage I can achive easily in the existing code. Below is the
code I have used to achive what I want. If user has pressed File-
Open, it returns string File::Open.
Then I will be doing the other way to get the ID from File::Open and
do SendMessage for replay.
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
UINT nID = LOWORD(wParam);//ID which generated the message
HWND hWndCtrl = (HWND)lParam;//control
int nCode = HIWORD(wParam);//type of message
if(nCode==0)
{
CString menuString,menuStr;
CMenu *pCMenu = GetMenu();
pCMenu->GetMenuString(LOWORD(wParam),menuStr,MF_BYCOMMAND);
BOOL found=false;
GetTclLogMenuString(pCMenu,menuStr,found,menuString);
AfxMessageBox(menuString,MB_OK,0);
}
return CMDIFrameWnd::OnCommand(wParam,lParam);
}
void CMainFrame::GetTclLogMenuString(CMenu *pCMenu, const CString
&inputStr, BOOL& isFound, CString& tclMenuStr)
{
if(pCMenu==0) return;
int count = pCMenu->GetMenuItemCount();
int i=0;
CString strMenuItem;
BOOL found=false;
while(i<count)
{
pCMenu->GetMenuString(i, strMenuItem, MF_BYPOSITION);
CString menuStr;
GetTclLogSubMenuString(pCMenu->GetSubMenu
(i),inputStr,found,menuStr);
if(found)
{
strMenuItem.Remove('&');
strMenuItem.Remove('.');
//Deletes the string after /t or /n
int pos = menuStr.Find('\t');
if(pos!=-1)
{
int charactersToDelete = menuStr.GetLength()-pos;
menuStr.Delete(pos,charactersToDelete);
}
tclMenuStr=strMenuItem;
tclMenuStr+="::";
tclMenuStr+=menuStr;
break;
}
++i;
}
}
void CMainFrame::GetTclLogSubMenuString(CMenu *pCMenu, const CString&
inputStr, BOOL &isFound, CString& tclMenuStr)
{
if(pCMenu==0) return;
int count = pCMenu->GetMenuItemCount();
int i=0;
CString strMenuItem;
while(!isFound && i<count)
{
pCMenu->GetMenuString(i,strMenuItem,MF_BYPOSITION);
if(strMenuItem.CompareNoCase(inputStr)==0)
{
strMenuItem.Remove('&');
strMenuItem.Remove('.');
tclMenuStr+=strMenuItem;
isFound=true;
break;
}
CMenu *pSubMenu = pCMenu->GetSubMenu(i);
if(pSubMenu)
{
tclMenuStr+=strMenuItem;
tclMenuStr.Remove('&');
tclMenuStr.Remove('.');
tclMenuStr+="::";
GetTclLogSubMenuString(pSubMenu, inputStr, isFound, tclMenuStr);
}
++i;
}
if(isFound) return;
if(i==count) tclMenuStr="";
}
I just wanted to know If MFC has provided some API to get the CMenu
given a SubMenu which I might not be aware and that could avoid me
writing the above code.
Please let me know if there exists better idea than this, considering
that there exists many menu items that needs to be logged, rather than
providing the logging at the function level.