 |
|
 |
Concise, precise, helpful
|
|
|
|
 |
|
|
 |
|
 |
This is a nice program, and much appreciated. However, a simple dialog application that used the control would complete its usefulness.
If this was done, could you make the entire project available as a download?
TIA,
|
|
|
|
 |
|
 |
I am trying to use CMenuEdit with a CDialogBar control. Does this class not work with CDialogBar, or am i using it wrong?
-- Steve
|
|
|
|
 |
|
 |
This class is a simple subclassed CEdit control, so there is no reason why it should not work. But I am not familiar with CDialogBars as I have never had a need to use them so I do not know if there is a gotcha to look out for.
Sonork 100.11743 Chicken Little
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
Within you lies the power for good - Use it!
|
|
|
|
 |
|
 |
I've read your article, and I want to ask you a small question: If I have a ComboBox, how can I modify a context menu of the editor of this ComboBox (I known that a combobox is combined by a Listbox and a edit). Please help me! Thanks
Never say Goodbye!
|
|
|
|
 |
|
 |
Better late then never
I had to do just what you want, so I finally figured it out.
Subclass the CComboBox, and add a CMenuEdit control variable to your class.
#include "MenuEdit.h"
class CMyComboBox : public CComboBox
{
...
protected:
CMenuEdit m_MyEditControl;
...Then add the PreSubclassWindow() virtual functionvoid CMyComboBox::PreSubclassWindow()
{
CComboBox::PreSubclassWindow();
m_MyEditControl.SubclassDlgItem(1001, this);
}
Sonork 100.11743 Chicken Little
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
Within you lies the power for good - Use it!
|
|
|
|
 |
|
 |
Thank for your help
Never say Goodbye!
|
|
|
|
 |
|
 |
Thank you very much for this elegant solution.
Hoc Ngo
|
|
|
|
 |
|
 |
I created a test CFormView app, included MenuEdit.h, added a CEdit control and changed it to type CMenuEdit. When I right click on the edit control the new menu shows up. Now, if I click on the part of the menu I added and have it execute a function that should return a string, how do I get access to that string so that I can copy it into the edit control?
|
|
|
|
 |
|
 |
I'm not quite sure where your problem is, but you could just call SetWindowText() on the returned value.
void CMyMenuEdit::OnMyMenuItem()
{
SetWindowText(MyFunctionThatReturnsAString());
}If this does not help, then could you please give me a little more detail (post some code) on your problem.
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
 |
|
 |
Duh. Sorry to have bothered you. I was in the middle of adding a dialog box when I added your code. So I was thinking (not thinking really) I had to return the result. It works great. Thanks for doing this.
|
|
|
|
 |
|
 |
It's a matter of preference, but I would choose to get TrackPopupMenu return the selected menu item ID, and handle it all in OnContextMenu. This means that the code in OnCommand doesn't get processed every time a WM_COMMAND message is received, just in case it was from the context menu.
To acheive this, the code from, and including, the call to TrackPopupMenu can be replaced with the following: int nCmd = menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
TPM_RETURNCMD | TPM_RIGHTBUTTON, point.x, point.y, this);
menu.DestroyMenu();
if (nCmd < 0)
return;
switch (nCmd)
{
case EM_UNDO:
case WM_CUT:
case WM_COPY:
case WM_CLEAR:
case WM_PASTE:
SendMessage(nCmd);
case ME_SELECTALL:
SendMessage(EM_SETSEL, 0, -1);
default:
SendMessage(WM_COMMAND, nCmd);
}
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
Thanks for this Paul.
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
 |
|
 |
TrackPopupMenu is defined to return a bool, is this an MSDN typo or ?
|
|
|
|
 |
|
 |
You are correct in saying that TrackPopupMenu is defined as returning a BOOL. However, the documentation for the Win32 function TrackPopupMenu describes a flag of TPM_RETURNCMD (for some reason omitted from the MFC docs), which returns a result to be taken as an int (don't forget that a BOOL is just an int anyway). That's how you can do what I described.
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
Cool, thanks for the heads up..
|
|
|
|
 |
|
 |
You should add break-s within the switch statement, otherwise all the text within edit is selected after a command was executed, which is quite annoying.
switch (nCmd)
{
case EM_UNDO:
case WM_CUT:
case WM_COPY:
case WM_CLEAR:
case WM_PASTE:
SendMessage(nCmd);
break;
case ME_SELECTALL:
SendMessage(EM_SETSEL, 0, -1);
break
default:
SendMessage(WM_COMMAND, nCmd);
}
TNX for this article, it saved me some reading.
|
|
|
|
 |
|
 |
You are absolutely correct - very careless of me! Well spotted!
(BTW, in your fix, you have left out a semi-colon )
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
Good class, but I found a few bits missing:
1. The menu is not being destroyed after TrackPopupMenu
2. The menu will not show in the correct place if invoked by the Context Menu key.
The solutions:
1. Insert the following code after the call to TrackPopupMenu: menu.DestroyMenu(); 2. Add the following code before the call to TrackPopupMenu:
if (point.x == -1 || point.y == -1)
{
CRect rc;
GetClientRect(&rc);
point = rc.CenterPoint();
ClientToScreen(&point);
}
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
Paul S. Vickery wrote:
1. The menu is not being destroyed after TrackPopupMenu
Paul S. Vickery wrote:
1. Insert the following code after the call to TrackPopupMenu:
menu.DestroyMenu();
From MSDN:
[quote]
CMenu::DestroyMenu
BOOL DestroyMenu( );
Return Value
Nonzero if the menu is destroyed; otherwise 0.
Remarks
Destroys the menu and any Windows resources that were used. The menu is detached from the CMenu object before it is destroyed. The Windows DestroyMenu function is automatically called in the CMenu destructor.
[/quote]
Paul S. Vickery wrote:
2. The menu will not show in the correct place if invoked by the Context Menu key.
Paul S. Vickery wrote:
2. Add the following code before the call to TrackPopupMenu:
...
Thanks for this Paul, I am a heavy mouse user and failed to notice this
Paul S. Vickery wrote:
"The way of a fool seems right to him, but a wise man listens to advice"
What are you saying? Is this meant for me?
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
 |
|
 |
OK, so you got me on the DestroyMenu: I often use HMENUs directly, where it is important that I remember to destroy them. I guess I've over-indoctrinated myself!
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
 |
|
 |
This solution seems to be working properly.
However it involves creating and using the derived class CMenuEdit. Is there a way to hook (intercept) the contex menu (of a CEdit) on a dialog level and then alter menu items from there?
Thanks,
Dejan
|
|
|
|
 |
|
 |
Not that I am aware of. If I knew how I would not have written this little class
Anyone else know
---
Blessed are those who can laugh at themselves, for they shall never cease to be amused
|
|
|
|
 |
|
 |
You can get the menu context handle with the WM_ENTERIDLE message like that:
void CMenuEdit::OnEnterIdle(UINT nWhy, CWnd* pWho)
{
CEdit::OnEnterIdle(nWhy, pWho);
if (nWhy == MSGF_MENU)
{
MENUBARINFO mbi;
memset(&mbi, 0, sizeof(MENUBARINFO));
mbi.cbSize = sizeof(MENUBARINFO);
GetMenuBarInfo(pWho->m_hWnd, OBJID_CLIENT, 0, &mbi);
if (GetMenuState(mbi.hMenu, 1001, MF_BYCOMMAND) == -1)
{
AppendMenu(mbi.hMenu, MF_STRING, 1001, "New item");
}
}
}
|
|
|
|
 |