Correct way of loading a menu from a resource?

Started by Quin, February 19, 2025, 05:01:59 PM

Previous topic - Next topic

airr

Quin, try removing the quotes around ID_MAINMENU....


AIR.

Vortex

Hi Quin,

Don't forget to link the object module with the compiled resource script. ( .res file )

The LoadMenu line should contain MAKEINTRESOURCE.

GUI "Test", PIXELS

$BCX_RESOURCE
#define IDM_EXIT 101
#define ID_MAINMENU 1001

ID_MAINMENU MENU
    BEGIN
        POPUP "&File"
        BEGIN
            MENUITEM "E&xit" IDM_EXIT
        END
    END
$BCX_RESOURCE

CONST ID_MAINMENU = 1001
CONST IDM_EXIT = 101

GLOBAL MainForm AS HWND

SUB FORMLOAD
    MainForm = BCX_FORM("Testing")
    SetMenu(MainForm, LoadMenu(BCX_HINSTANCE, MAKEINTRESOURCE(ID_MAINMENU)))
    SHOW(MainForm)
END SUB

BEGIN EVENTS
    SELECT CASE CBMSG
    CASE WM_COMMAND
        IF CBCTL = IDM_EXIT THEN PostMessage(hWnd, WM_CLOSE, 0, 0)
    END SELECT
END EVENTS

Quin

Hi all,
thanks for the responses! Unfortunately though I'm unable to make this work still, even with all the batch files provided. I changed my original code slightly after seeing Robert's posted example to remove a comma, but that still hasn't fixed it and LoadMenu() always returns NULL. I'm clearly missing something here, but I'm not sure what. Can anyone here get this to compile and run correctly? Tried with Pelles and Mingw.

Gui "Test", Pixels

$Bcx_Resource
#define IDM_EXIT 101

"ID_MAINMENU" MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit" IDM_EXIT
END
END
$Bcx_Resource

Global MainForm As HWND

Sub Formload
    MainForm = BCX_Form("Testing")
    SetMenu(MainForm, LoadMenu(Bcx_Hinstance, "ID_MAINMENU"))
    Show(MainForm)
End Sub

Begin Events
End Events


airr

Just an idea, with a modified PW64.bat:


@SETLOCAL enabledelayedexpansion
@ECHO OFF

CALL  %~dp0\Config.bat

@IF NOT EXIST %1.c @ECHO %1.c was not found. Operation aborted.
@IF NOT EXIST %1.c GOTO Done
@IF EXIST %1.exe @DEL %1.exe

@SET  PATH=%PellesFolder%\Bin;%PATH%;
@SET  INCLUDE=%PellesFolder%\Include;%PellesFolder%\Include\Win;%INCLUDE%;
@SET  LIB=%PellesFolder%\Lib;%PellesFolder%\Lib\Win64;%LIB%;

@SET  PoccOPTS= /Go /Gn /W1 /Gd /Ze /Zx /Tx64-coff /D NTDDI_VERSION=0x0A000007 /std:c17 /fp:precise
@SET  PolinkOPTS= -release -machine:x64 /subsystem:windows,5.02 /STACK:10485760               
@SET  PolinkLIBS= kernel32.lib advapi32.lib delayimp64.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib ole32.lib oleaut32.lib

@SET RES=

@ECHO ON
@ECHO **************************************************************************
@IF EXIST "%1__.rc" (
    @SET RES="%1__.res"
    @ECHO Pelles C is creating "%1__.res"
    @call %PellesFolder%\bin\porc "%1__.rc"
)

@IF EXIST %1.c @ECHO Pelles C is compiling [ %1.c ] as a 64-bit GUI application. Duh

@call %PellesFolder%\bin\pocc    %PoccOPTS%    "%1.c"
@call %PellesFolder%\bin\polink  %PolinkLIBS%  %PolinkOPTS%   "%1.obj"  %RES% %2 %3 %4 %5 %6 %7 %8 %9

@IF EXIST %1.exe @ECHO Pelles C built [ %1.exe ]

@ECHO OFF

:Done
@ENDLOCAL


AIR.

Robert

Quote from: Vortex on February 20, 2025, 12:07:51 PM
An interesting but requiring more effort method is to use binary resource templates :

SUB FORMLOAD

    SET MenuRsrc [] AS UCHAR

        0, 0, 0, 0, 16, 0, 38, 0, 70, 0, 105, 0, 108, 0, 101, 0, _
        0, 0, 0, 0, 66, 156, 38, 0, 79, 0, 112, 0, 101, 0, 110, 0, _
        32, 0, 70, 0, 105, 0, 108, 0, 101, 0, 0, 0, 0, 0, 68, 156, _
        38, 0, 78, 0, 101, 0, 119, 0, 32, 0, 102, 0, 105, 0, 108, 0, _
        101, 0, 0, 0, 0, 0, 67, 156, 83, 0, 97, 0, 118, 0, 101, 0, _
        32, 0, 38, 0, 65, 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
        128, 0, 65, 156, 69, 0, 38, 0, 120, 0, 105, 0, 116, 0, 0, 0, _
        144, 0, 38, 0, 72, 0, 101, 0, 108, 0, 112, 0, 0, 0, 0, 0, _
        69, 156, 38, 0, 72, 0, 101, 0, 108, 0, 112, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 128, 0, 70, 156, 38, 0, 65, 0, 98, 0, 111, 0, _
        117, 0, 116, 0, 0, 0, 0, 0

    END SET
   
    Form1 = BCX_FORM("$BCX_RESOURCE Demo", 0, 0, 480, 320, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN)
    SetMenu(Form1, LoadMenuIndirect(MenuRsrc))
    CENTER(Form1)
    SHOW(Form1)
    SHOW(hTool)
END SUB


I extracted the binary resource data from the compiled resource script with my res2bin tool :

res2bin Rsrc.res

Resource type:Menu OFFSET=0 SIZE=A6

Very cool !  8)
Thanks Vortex.

Vortex

An interesting but requiring more effort method is to use binary resource templates :

SUB FORMLOAD

    SET MenuRsrc [] AS UCHAR

        0, 0, 0, 0, 16, 0, 38, 0, 70, 0, 105, 0, 108, 0, 101, 0, _
        0, 0, 0, 0, 66, 156, 38, 0, 79, 0, 112, 0, 101, 0, 110, 0, _
        32, 0, 70, 0, 105, 0, 108, 0, 101, 0, 0, 0, 0, 0, 68, 156, _
        38, 0, 78, 0, 101, 0, 119, 0, 32, 0, 102, 0, 105, 0, 108, 0, _
        101, 0, 0, 0, 0, 0, 67, 156, 83, 0, 97, 0, 118, 0, 101, 0, _
        32, 0, 38, 0, 65, 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
        128, 0, 65, 156, 69, 0, 38, 0, 120, 0, 105, 0, 116, 0, 0, 0, _
        144, 0, 38, 0, 72, 0, 101, 0, 108, 0, 112, 0, 0, 0, 0, 0, _
        69, 156, 38, 0, 72, 0, 101, 0, 108, 0, 112, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 128, 0, 70, 156, 38, 0, 65, 0, 98, 0, 111, 0, _
        117, 0, 116, 0, 0, 0, 0, 0

    END SET
   
    Form1 = BCX_FORM("$BCX_RESOURCE Demo", 0, 0, 480, 320, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN)
    SetMenu(Form1, LoadMenuIndirect(MenuRsrc))
    CENTER(Form1)
    SHOW(Form1)
    SHOW(hTool)
END SUB


I extracted the binary resource data from the compiled resource script with my res2bin tool :

res2bin Rsrc.res

Resource type:Menu OFFSET=0 SIZE=A6

Robert

Quote from: Quin on February 19, 2025, 05:01:59 PM
I'm trying to use resources for menus in my application, but having no luck. I'm sure it's something I'm doing wrong, but I've been hacking at this for a couple hours and am beginning to get a headache, so figured I'd get some of the genius minds here to have a look. Here's the smallest example I have:

Gui "Test", Pixels

$Bcx_Resource
#define IDM_EXIT 101

"ID_MAINMENU" MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit", IDM_EXIT
    END
END
$Bcx_Resource

Global MainForm As HWND

Sub Formload
    MainForm = BCX_Form("Testing")
    SetMenu(MainForm, LoadMenu(Bcx_Hinstance, "ID_MAINMENU"))
    Show(MainForm)
End Sub

Begin Events
End Events

LoadMenu is seemingly returning NULL, so something must be wrong with my menu template or how I'm using it, but I just can't figure it out.
Thanks for any help!

Hi Quin:

Below is some BCX code using $BCX_RESOURCE with menus. The code is based on a ToolBar Demo originally written by Ad Rienks in 2011.

I have added Pelles C compilation directives to the beginning of the code so it can be easily compiled from the command line using this two line batch.


CALL povars32.bat
bc test32


The batch will translate and compile to a 32 bit .exe named test32.exe

Save the BCX code below as test32.bas



$IPRINT_OFF
 
$RESOURCE "$PELLES$\bin\porc.exe"

$COMPILER "$PELLES$\Bin\pocc -W1 -Gd -Go -Ze -Zx -Tx86-coff $FILE$.c"

$LINKER "$PELLES$\Bin\polink _
                     -release _
                -machine:ix86 _
           -subsystem:windows _
              -OUT:$FILE$.exe _
                   $FILE$.obj _
                 $FILE$__.res"

$BCX_RESOURCE
#define ID_MAINMENU      102
#define ID_FILE_EXIT   40001
#define ID_FILE_OPEN   40002
#define ID_FILE_SAVEAS 40003
#define ID_FILE_NEW    40004
#define ID_HELP        40005
#define ID_ABOUT       40006

ID_MAINMENU MENU DISCARDABLE
BEGIN
POPUP "&File"
  BEGIN
   MENUITEM "&Open File" ID_FILE_OPEN
   MENUITEM "&New file" ID_FILE_NEW
   MENUITEM "Save &As"   ID_FILE_SAVEAS
   MENUITEM SEPARATOR
   MENUITEM "E&xit"      ID_FILE_EXIT
  END
POPUP "&Help"
  BEGIN
   MENUITEM "&Help"      ID_HELP
   MENUITEM SEPARATOR
   MENUITEM "&About"     ID_ABOUT
  END
END
$BCX_RESOURCE

CONST ID_MAINMENU = 102
ENUM
  ID_FILE_EXIT = 40001
  ID_FILE_OPEN
  ID_FILE_SAVEAS
  ID_FILE_NEW
  ID_HELP
  ID_ABOUT
  ID_TOOLBAR
END ENUM

GUI "BCXResourceDemo", PIXELS

GLOBAL Form1 AS hwnd
GLOBAL hTool AS hwnd

SUB FORMLOAD
  Form1 = BCX_FORM("$BCX_RESOURCE Demo", 0, 0, 480, 320, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN)
  SetMenu(Form1, LoadMenu(BCX_HINSTANCE, MAKEINTRESOURCE(ID_MAINMENU)))
  CENTER(Form1)
  SHOW(Form1)
  SHOW(hTool)
END SUB

BEGIN EVENTS
  SELECT CASE CBMSG
  CASE WM_COMMAND
   IF CBCTL = ID_FILE_EXIT THEN PostMessage(hWnd, WM_CLOSE, 0, 0)
   IF CBCTL = ID_FILE_OPEN THEN GETFILENAME$("", "|*.*")
   IF CBCTL = ID_FILE_NEW THEN MSGBOX "$BCX_RESOURCE Demo" + CR$ + "Coded by Ad Rienks", "New", MB_ICONINFORMATION
   IF CBCTL = ID_FILE_SAVEAS THEN GETFILENAME$("", "|*.*", 1)
   IF CBCTL = ID_HELP THEN MSGBOX "More help is not (yet) available", "Help?", MB_ICONINFORMATION
   IF CBCTL = ID_ABOUT THEN MSGBOX "$BCX_RESOURCE Demo" + CR$ + "Coded by Ad Rienks", "About", MB_ICONINFORMATION
  END SELECT
END EVENTS




Quin

I'm trying to use resources for menus in my application, but having no luck. I'm sure it's something I'm doing wrong, but I've been hacking at this for a couple hours and am beginning to get a headache, so figured I'd get some of the genius minds here to have a look. Here's the smallest example I have:

Gui "Test", Pixels

$Bcx_Resource
#define IDM_EXIT 101


"ID_MAINMENU" MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit", IDM_EXIT
    END
END
$Bcx_Resource

Global MainForm As HWND

Sub Formload
    MainForm = BCX_Form("Testing")
    SetMenu(MainForm, LoadMenu(Bcx_Hinstance, "ID_MAINMENU"))
    Show(MainForm)
End Sub

Begin Events
End Events

LoadMenu is seemingly returning NULL, so something must be wrong with my menu template or how I'm using it, but I just can't figure it out.
Thanks for any help!