.rc file issues

Hi,

I'm trying to follow this (http://www.winprog.org/tutorial/menus.html) tutorial, but I'm running across a consistent issue. Whenever I try to compile and run the menu_one program, I'm not getting a menu as I should do. There are no error messages, so I'm not quite sure why it isn't functioning properly. Any advice appreciated greatly.
Unfortunately, the link to the tutorial that you mentioned, appears to be broken. Since your topic heading is ".rc file issues", I am assuming that you are using a resource file, as well as a resource header file (.h).

One common problem comes from trying to load the menu directly by name. There seems to be endless documentation, claiming that you can do this. It never seems to work. Instead, the "MAKEINTRESOURCE" macro is needed. In your windows class definition, the line assigning the menu needs to look something like this:

 
wndclass.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);


Or, if the menu is being dynamically created, using LoadMenu(), that function would need to look like this:

 
LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));


The macro "IDR_MENU1" is the name assigned to the menu in the resource (.rc) file. Check your resource file, as you may have something different.

If this doesn't solve your problem, you may need to post your code.
Last edited on
the link to the tutorial that you mentioned, appears to be broken

It's kind of this site that's a little broken.
The ending parenthesis is being considered to be part of the link.
Here it is without the parens:
http://www.winprog.org/tutorial/menus.html

Which example are you using? Is it "Example One", using the resource file? Or, "Example Two", the dynamically created menu. You cannot use both at the same time. Your program will get confused.

In this tutorial, your menu macro is "IDR_MYMENU".
Did you download the source files? If not, then do it. The tutorial pages don't have all the code needed to create functional Win32 API apps.

What compiler/IDE are you using to create the example apps?

PLUS, MS changed the API interfacing in subtle (and not subtle) ways. 16-bit Windows doesn't exist any more, no more long pointers. Replace LPTSTR with PTSTR, LPSTR with PSTR.

Win98 and earlier are dead.
Here's some simple but old code I just dug up from around 2012 that shows about what Anachronon is talking about with rc files and the MAKEINTORESOURCE macro....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* Mnu02.rc  */
#define IDR_MAIN_MENU                        2000
#define IDM_FILE_OPEN                        2100
#define IDM_FILE_EXIT                        2105

IDR_MAIN_MENU MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&Open...",      IDM_FILE_OPEN
        MENUITEM "E&xit",         IDM_FILE_EXIT
    END
END


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Mnu02.cpp
#include <windows.h>

#define IDR_MAIN_MENU                        2000
#define IDM_FILE_OPEN                        2100
#define IDM_FILE_EXIT                        2105

long __stdcall WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 if(message==WM_DESTROY)
    PostQuitMessage(0);
 else
    return DefWindowProc(hwnd, message, wParam, lParam);

 return 0;
}

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpszArgument, int nCmdShow)
{
 char szClassName[ ] = "CodeBlocksWindowsApp";
 MSG messages;
 WNDCLASS wc;
 HWND hwnd;

 wc.hInstance     = hInstance,                         wc.lpszClassName  = szClassName;
 wc.lpfnWndProc   = WindowProcedure,                   wc.style          = 0;
 wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION),   wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
 wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAIN_MENU),    wc.cbClsExtra     = 0;
 wc.cbWndExtra    = 0,                                 wc.hbrBackground  = (HBRUSH)COLOR_BACKGROUND;
 RegisterClass(&wc);
 hwnd=CreateWindow(szClassName,"Template",WS_OVERLAPPEDWINDOW,50,50,544,375,HWND_DESKTOP,NULL,hInstance,NULL);
 ShowWindow (hwnd, nCmdShow);
 while(GetMessage (&messages, NULL, 0, 0))
 {
    TranslateMessage(&messages);
    DispatchMessage(&messages);
 }

 return messages.wParam;
}


At that time I was only doing x86 code mostly with Mingw. Haven't tested with VStudio 2019 or x64 (Looks suspicious for x64). Hope it helps.
Last edited on
@freddie1,

VS 2019 defaults to Unicode. To get your code to work with VS2019 x86/x64 a couple of changes need to be made:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <windows.h>

#define IDR_MAIN_MENU                        2000
#define IDM_FILE_OPEN                        2100
#define IDM_FILE_EXIT                        2105

LRESULT __stdcall WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   if (message == WM_DESTROY)
      PostQuitMessage(0);
   else
      return DefWindowProc(hwnd, message, wParam, lParam);

   return 0;
}

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrev, PSTR lpszArgument, int nCmdShow)
{
   WCHAR szClassName[] = L"CodeBlocksWindowsApp";
   MSG messages;
   WNDCLASS wc;
   HWND hwnd;

   wc.hInstance = hInstance, wc.lpszClassName = szClassName;
   wc.lpfnWndProc = WindowProcedure, wc.style = 0;
   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION), wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAIN_MENU), wc.cbClsExtra = 0;
   wc.cbWndExtra = 0, wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
   RegisterClass(&wc);
   hwnd = CreateWindow(szClassName, L"Template", WS_OVERLAPPEDWINDOW, 50, 50, 544, 375, HWND_DESKTOP, NULL, hInstance, NULL);
   ShowWindow(hwnd, nCmdShow);
   while (GetMessage(&messages, NULL, 0, 0))
   {
      TranslateMessage(&messages);
      DispatchMessage(&messages);
   }

   return messages.wParam;
}

There's a warning wc is uninitialized; another warning the WinMain return is converting from WPARAM to int, possible loss of data (x64 only, x86 doesn't complain).

And yet another warning WinMain is not properly SAL annotated.
To get rid of the WinMain SAL annotation warning:

17
18
int __stdcall WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrev,
                      _In_ PSTR lpszArgument, _In_ int nCmdShow)

*Ick!*

I am not overly fond of SAL, yet I understand the whys of using it. In most Win32 API uses I'd put up with the warning instead of trying to comply with the excess verbiage of annotating.
Last edited on
To get rid of the WinMain SAL annotation warning:
Put this above all include files.

1
2
3
#ifdef _MSC_VER
  #pragma warning(disable: 28251)
#endif 
Disabling warnings is IMO using a nuke to swat a fly. Warnings are generated for a reason. Either I ignore them or I do what is needed to resolve them.

With SAL warnings they are infinitely ignore-able.
Topic archived. No new replies allowed.