What's new

fed up with mfc

mesman00

What's that...?
ok i keep posting simple problems here, so i probably sound liek a total noob. but i don't care. i have created a menu using msvc++ resource creator tool. here the actual code generated by msvc++

Code:
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_MENU1 MENU 
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit",                       IDM_FileExit
    END
END

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

notice the menu specific code under heading IDR_MENU1. so, when i create the window i use the following method.

Code:
Create(NULL, "DICOM SR Viewer", WS_OVERLAPPEDWINDOW, CRect(0, 0, 800, 600), NULL, "IDR_MENU1");

this should work, and i see no reason why it doesn't, but i get an assertion error right when the program loads. and the assertion is definately caused when i try to add the menu to the create method. if i don't add the menu the program executes fine. otherwise i don't even get to see the window. here is a pic of the error:
 
Last edited:

zenogais

New member
You need to use the MAKEINTRESOURCE() macro for the menu, here's my window code for NeoPSX:

Code:
NeoMain::NeoMain()
: m_strVersion("NeoPSX 2.0.0")
{
	//===================================================
	// Create The NeoPSX Main Window
	//===================================================
	CRect customRect(0, 0, 420,400);
	Create(NULL, m_strVersion.c_str(), WS_OVERLAPPEDWINDOW, customRect, NULL, MAKEINTRESOURCE(IDR_MAINMENU));
}
 

Doomulation

?????????????????????????
Lol, this is a classic win32 mistake, not mfc :icecream:
ALWAYS use MAKEINTRESOURCE UNLESS your resouces are surrounded by quotes (""). I learned from this mistake long ago... hehe, otherwise just do it by trail-and-error :evil:
 
OP
mesman00

mesman00

What's that...?
ok one more thing now. i am trying to create a CMenu so i can edit my menu's apperance (check marks, enable selections, etc.) i do:

Code:
menu = new CMenu();	
menu->CreateMenu();
menu->LoadMenu(MAKEINTRESOURCE(IDR_MainMenu));

however, i get another assertion error, this time caused by the third line of code in the sequence. can you come to my rescue yet again?

btw i changed the name of the menu resource to IDR_MainMenu
 
Last edited:

zenogais

New member
mesman00 said:
ok one more thing now. i am trying to create a CMenu so i can edit my menu's apperance (check marks, enable selections, etc.) i do:

Code:
menu = new CMenu();	
menu->CreateMenu();
menu->LoadMenu(MAKEINTRESOURCE(IDR_MainMenu));

however, i get another assertion error, this time caused by the third line of code in the sequence. can you come to my rescue yet again?

btw i changed the name of the menu resource to IDR_MainMenu

My recommendation, swap CreateMenu and LoadMenu.
Code:
menu = new CMenu();	
menu->LoadMenu(MAKEINTRESOURCE(IDR_MainMenu));
menu->CreateMenu();
 
OP
mesman00

mesman00

What's that...?
no dice. already tried that.

edit* ahh i got it. did some reading in the msdn library. found some new stuff that i did'nt see before. you can only load a menu, or create a menu, can't do both.
 
OP
mesman00

mesman00

What's that...?
ok now i'm having trouble with actually using the CMenu class. here is my code:

Code:
	unsigned int previousMenuState = mainMenu->EnableMenuItem(IDM_ViewBy_XML, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);	

	if(previousMenuState == MF_ENABLED)
	{
		MessageBox("previously enabled");
	}

this code is in one of my methods that is exectued when a certain menu item is clicked. so, i click the menu item for the first time, and the code is executed, and it prints the message "previously enabled" since that is the state it starts in when the program is executed. This tells me that previousMenuState is equal to MF_ENABLED, which is correct. However, the menu item with the id IDM_ViewBy_XML doesn't become disabled or gray. However, if i click the same menu item again the message "previously enabled" is no longer printed, leading me to believe that previousMessageState is no longer MF_ENABLED, and this is correct because the menu item should be MF_DISABLED and MF_GRAYED after calling EnableMenuItem() for the first, and then all of the suceeding times.
So to me it looks like the code is executing correctly and the menu properties are being changed, but it is not being updated in the menu. By the way, i have

Code:
m_bAutoMenuEnable = FALSE;

in my CMainWin (inherits CFrameWnd properties) constructor, so no ON_UPDATE_COMMAND_UI or ON_COMMAND handlers are
needed. Also, if i use the MAKEINTRESOURCE() macro in the code like this:

Code:
	unsigned int previousMenuState = mainMenu->EnableMenuItem(MAKEINTRESOURCE(IDM_ViewBy_XML), MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

i get the following error:

Code:
error C2664: 'EnableMenuItem' : cannot convert parameter 1 from 'char *' to 'unsigned int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast

with all that said, who can help?
 

smcd

Active member
Each menu item has a unique identifier (by default starting at 40000 if I remember correctly)... you need to specify this for the first parameter since you are using MF_BYCOMMAND, you do NOT want to use MAKEINTRESOURCE there.

For example, /* assumes ID_FILE_EXIT is the #define for the File->Exit menu item */
mainMenu->EnableMenuItem(ID_FILE_EXIT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);

However, according to http://msdn.microsoft.com/msdnmag/issues/0700/c/default.aspx you don't want to use this at all. (look at the first question/answer)
 
Last edited:

Doomulation

?????????????????????????
Ok not entirely sure why all this happens but I can try to guide you =)
You see, MF_GRAY both disabled the menu and dims it, so MF_DISABLE isn't really needed. You can delete that.
And using MAKEINTRESOURCE is a no-no for menu functions. If you look at CreateDialog, you'll see the the resource argument is of type char*. The MAKEINTRESOURCE actually returns a char*. You should read up a little on those functions to see how the macro realls works. That's why you get a compile error when trying to use it ;)

About your menues there...
CMenu->LoadMenu is used to load a menu from a resource. This is the same as the win32 api LoadMenu.
CMenu->CreateMenu creates a new menu resources. After that, you can append menues dynamically using functions such as AppendMenu.
Make no mistake, LoadMenu creates a new menu resource from the resource specified and attaches it to the cmenu class.
See the item in help for more info :)

I hope this will help you!

This is a class I built around the win32 api for menues. It illustrates how the EnableMenuItem works. In MFC, this pretty much works the same without the hwnd parameter.

Code:
class CMenu
{
public:
	CMenu(HWND hMenu);
	CMenu();
	void SethMenu(HMENU hMenu) { m_hMenu = hMenu; }
	bool Enable(int item) { return EnableMenuItem(m_hMenu,item,MF_BYPOSITION|MF_ENABLED); }
	bool Disable(int item) { return EnableMenuItem(m_hMenu,item,MF_BYPOSITION|MF_GRAYED); }
private:
	HMENU m_hMenu;
};

Oh and, you'd replace MY_BYPOSITION with MF_BYCOMMAND (or remove it completly; it's interpreted as default) so that you can pass the id if the menu you're trying to do it with.
 
OP
mesman00

mesman00

What's that...?
Ok not entirely sure why all this happens but I can try to guide you =)
You see, MF_GRAY both disabled the menu and dims it, so MF_DISABLE isn't really needed. You can delete that.
And using MAKEINTRESOURCE is a no-no for menu functions. If you look at CreateDialog, you'll see the the resource argument is of type char*. The MAKEINTRESOURCE actually returns a char*. You should read up a little on those functions to see how the macro realls works. That's why you get a compile error when trying to use it

About your menues there...
CMenu->LoadMenu is used to load a menu from a resource. This is the same as the win32 api LoadMenu.
CMenu->CreateMenu creates a new menu resources. After that, you can append menues dynamically using functions such as AppendMenu.
Make no mistake, LoadMenu creates a new menu resource from the resource specified and attaches it to the cmenu class.
See the item in help for more info

yah i had figured this much out from reading the msdn library. however, i am still having the same problem. is there a special method, maybe predefined, that i need to overload and put all my menu modifying code in? i really can't figure out why this isn't working.
 
OP
mesman00

mesman00

What's that...?
Doomulation said:
I don't know much about mdi or sdi applications.
However, read the link sethmcdoogle posted:
http://msdn.microsoft.com/msdnmag/i.../c/default.aspx

First question.
For the record, I think mdi and sdi are bad for anything but word, wordpad or notepad or such. And as such, I avoid them. But that's up to you to decide.

that app i'm writing only has a web browser and a status bar, so an sdi app gets the job done nicely.
 
OP
mesman00

mesman00

What's that...?
ok this is getting me pissed. i wrote a little application with a window and status bar to represent what is happeneing. doom, i took your CMenu class as an example and used it to to see if using the regular win32 api menu functions would work. sure enough, it doesn't. but check this out:

Code:
	ChMenu test(IDR_MainMenu);
	test.Disable(IDM_ViewBy_XML);
	int status = GetMenuState(test.getm_hMenu(), IDM_ViewBy_XML, MF_BYCOMMAND);
	if(status == MF_GRAYED)
	{
		MessageBox("grayed");
	}

i run this in my CMainFrame (inherits CFrameWnd) constructor. and the message "grayed" is printed. thus that menu item has the grayed property, but for some reason it isn't displaying. here is the source of this small app i wrote quickly. take a look at it, tell me if you can find what might be happening. thanks alot, i appreciate it. btw, its not really commented, but you should be able to understand everything. the compiler i used was msvc++ 6.0, if you wanna use another compiler just create a new project and add my files to it.
 

Doomulation

?????????????????????????
According to the faq in the link, you should do menu changes in a certain event. By overriding the virtual function, there you provide code to change the menu states...

But... I'm bad on sdi and mdi apps... actually, never really used 'em... :plain:
I've always used dialog. But say what, I can try to find out something because my old visual c++ 6 book which lies around here covers 'em...
 
OP
mesman00

mesman00

What's that...?
Doomulation said:
According to the faq in the link, you should do menu changes in a certain event. By overriding the virtual function, there you provide code to change the menu states...

But... I'm bad on sdi and mdi apps... actually, never really used 'em... :plain:
I've always used dialog. But say what, I can try to find out something because my old visual c++ 6 book which lies around here covers 'em...

yah, i've done them in an event as well, same thing.
 
OP
mesman00

mesman00

What's that...?
alright, got everything good and working. next time i should learn to read the whole link someone posts. eeeek. thanks alot.
 

Top