-
Menu
Hi again.
I was readin this tutorial on menus, an I tried making one of my own.
Test.cpp :
Code:
#include <windows.h>
#include "resource.h"
const char g_szClassName[] = "WindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 11 );
wc.lpszMenuName = MAKEINTRESOURCE(IDR_Menu);
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"Windows Application",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 250, 250,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
Here's Menu.rc :
Code:
#include "resource.h"
IDR_Menu MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&STUFF"
BEGIN
MENUITEM "&Go", ID_STUFF_GO
MENUITEM "Go somewhere else", 13, GRAYED
END
END
And finally, resource.h :
Code:
#define IDR_Menu 1
#define ID_FILE_EXIT 12
#define ID_STUFF_GO 13
I realize that I may not have needed to post the entire code, but better be on the safe side.
Anyway, I was wondering what I've done wrong. It does compile with no errors or warnings, but when it is run, the menu simply isn't there.
Any advice ?
Cheers for any help provided. :)
-
Hmm, seems reasonable, you're specifying the menu in the class instead of in the CreateWindowEx call, which should work. I'm gonna roll the dice here and say that making IDR_Menu (Convention suggests constants to be all caps incidentally) equal to 1 may be causing a conflict with something internal to resource handling. Go with a big number instead, like 0x6969 (My usual ;)).
After changing this, make sure that you rebuild all sources (otherwise the compiler may try working with cached include files that contain old info). "Rebuild All" on MSVC's Build menu.
-
I did what you suggested, and rebuilt the project, but there wasn't any difference to be honest. The menu is still not there. Oh, and I also changed Menu to MENU. I know thats not gonna change anythin, but it's worth a shot right ?
Thanks for takin the time to try to help me out SMurf.
It's greatly appriciated. ;)
-
Code:
MENUITEM "&Go", ID_STUFF_GO
MENUITEM "Go somewhere else", 13, GRAYED
ID_STUFF_GO is defined as 13 and you are using 13 for "go somewhere else"
-
I know. I only noticed that a few hours ago, but after changing it, it still didn't work. Sorry, I'll edit that on the origional post now.
EDIT : Damn, can't edit it. Oh well
-
Which compiler are you using?
Make sure the resource script has been added to your project.
If you're using Dev-C++, make sure it's been included for compilation by going to
Project -> Project Options -> Files
-
Oh, yeah. I am using Dev-C++. Haven't got access to a compiler at the mo, but I'll try this later.
Cheers for the tips people.
-
Yeah ! Success ! Thanks for all your help.
I wish I was as clever as all of you.
EDIT: I really do. It's stopped working again now.
I just opened it, compiled everything, and on resource.h, it came up with : No rule to make resource.o stop. The same happens with Menu.rc, with the exeption of it saying : No rule to make Menu.o stop. This has really stumped me, as there is no such file called Menu.o or resource.o. What's goin' on ? :confused:
Oh, and I forgot to say that no code has changed.
-
The *.o files are objects; they are what source and, in the case of your particular error, resource scripts (*.rc) are usually compiled into. The linker then combines i.e. links these into your final, built project, usually an executable (*.exe).
The object files don't exist because the compiler doesn't know how to create them. That error may arise for a number of reasons, for example, you didn't include the resource script (Menu.rc) in your project.
Try 'project menu --> add to project' to make sure the resource script and resource header (Menu.rc and resource.h) are actually included in your project then 'Execute menu --> clean' followed by a 'rebuild all' and see if that makes a difference.
-
Make sure you're not trying to compile your resource script as C/C++ code.
-
Ta just realized that I also need to include the header in the project. But it worked before without the header. Wierd. Oh well thanks for your replies, it's working now.
-
OK, I am having a very similar problem. This code is pretty much cut and past from The Forgers web site.
main.cpp
Code:
#include <windows.h>
#include "resource.h"
// define window class name
const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_LBUTTONDOWN: {
char szFileName[MAX_PATH];
HINSTANCE hInstance = GetModuleHandle(NULL);
GetModuleFileName(hInstance, szFileName, MAX_PATH);
MessageBox(hwnd, szFileName, "This program is:",
MB_OK | MB_ICONINFORMATION);
break;
}
case WM_CLOSE :
DestroyWindow(hwnd);
break;
case WM_DESTROY :
PostQuitMessage(0);
break;
default :
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
//Step 1: Registering the Window Class
HWND hwnd;
MSG Msg;
WNDCLASSEX wc; // windows class structure
wc.cbSize = sizeof(WNDCLASSEX);//size of the structure
wc.style = 0; //class style
wc.lpfnWndProc = WndProc; //pointer to the procedure for this class
wc.cbClsExtra = 0; //extra memory allocated for this class
wc.cbWndExtra = 0; //extra memory allocated per window
wc.hInstance = hInstance; //handle to the application
wc.hIcon = LoadIcon(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_MYICON));//large icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//cursor style
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);//background brush color
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);//name of a menu resource
wc.lpszClassName = g_szClassName;//class name
wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_MYICON),
IMAGE_ICON, 16, 16, 0);//small icon for task bar
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, // extended windows style
g_szClassName, // class name (from above step)
"A Simple Window", // window title
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // x coord for top left corner of window
CW_USEDEFAULT, // y coord for top left corner of window
640, 420, // width and length of window
NULL, // parent window handle
NULL, // menu handle
hInstance, // application handle
NULL); // pointer to window creation data
if(hwnd == NULL) { // check if window creation failed
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
resource.h
Code:
#define IDR_MYMENU 101
#define IDI_MYICON 201
#define ID_FILE_EXIT 9001
#define ID_STUFF_GO 9002
and menu.rc
Code:
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&Stuff"
BEGIN
MENUITEM "&Go", ID_STUFF_GO
MENUITEM "G&o Somewhere Else", 0, GRAYED
END
END
IDI_MYICON ICON "C:\Dev-Cpp\Icons\mainicon.ico"
and here is my compile log
Code:
Compiler: Default compiler
Building Makefile: "C:\Dev-Cpp\References\The_Forger WIN_Tutorials\Chapter 1 Basics\#6, Menus&Icons\Makefile.win"
Executing make...
make.exe -f "C:\Dev-Cpp\References\The_Forger WIN_Tutorials\Chapter 1 Basics\#6, Menus&Icons\Makefile.win" all
g++.exe -D__DEBUG__ -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" -g3
windres.exe -i Menus&Icons_private.rc --input-format=rc -o Menus&Icons_private.res -O coff
windres.exe: Menus: No such file or directory
'Icons_private.rc' is not recognized as an internal or external command,
operable program or batch file.
'Icons_private.res' is not recognized as an internal or external command,
operable program or batch file.
make.exe: *** [Menus&Icons_private.res] Error 1
Execution terminated
this has really baffeled me because it worked the first time I put it in, but has not worked at all after that first time.
everything is included in the project and I have tried the clean and rebuild but that did not change anything.
As Dante Shamest suggested, I looked Under the Project Options, the .rc file has the box for 'Compile as C/C++ Code'
checked but it is grayed out and I cannot change it.
I am not sure where the 'Menus', 'Icons_private.rc' and 'Icons_private.res' came from, as they are not anything
I put in. I am guessing that the compiled automatically creates the '_private' files but I am lost on the 'Menus' thing.
Many thanks in advance to anyone who can help!
-
The forger's tutorial is where I got the base code from too. Sorry, but I don't think I can help at all. All I did was add the resource header to the project, and include the .rc file in compilation. After that, it came up with some wierd errors in the header, but I just added a newline after the second definition, and it worked fine.
If you've done all this, exept the definition thing, then I'm sorry, but I haven't a clue what's wrong. Oh, and I also would like to know what these "private files" are. They confuse me.
-
Well, I deleted everything I had and re typed it in and now it works fine...