News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Getting my head around resource file compilation

Started by Anaryl, February 25, 2016, 11:53:18 PM

Previous topic - Next topic

Anaryl

Hello there, me again!

Just working through some examples - and I was playing around with this tutorial here http://win32assembly.programminghorizon.com/tut8.html

Anyways so I wrote up the resource file in notepad++ and it seems to all compile and link okay - except that .exe doesn't have any menus!

This got me wondering how masm determines what resource file to use and where it's explicitly referenced in the asm file and how do I ensure that it is actually calling it correctly. I get that I can type the resource file and it shows the proper resource file when i link the obj file - I'm not sure as to exactly how it knows which one to look for. Are there naming conventions that I should observe? Anything else I should watch out for.

#define IDM_TEST 1
#define IDM_HELLO 2
#define IDM_GOODBYE 3
#define IDM_EXIT 4

FirstMenu
{
POPUP "&PopUp"
{
MENUITEM "&Say Hello", IDM_HELLO
MENUITEM "Say &Goodbye", IDM_GOODBYE
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
}
MENUITEM "&Test", IDM_TEST
}


.386
.model flat, stdcall
option casemap :none

WinMain proto :DWORD, :DWORD, :DWORD, :DWORD

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
ClassName db "SimpleWinClass", 0
AppName db "Our First Window", 0
MenuName db "FirstMenu", 0
Test_string db "You selected Test menu item", 0
Hello_string db "Hello, my friend", 0
Goodbye_string db "See you again, bye", 0

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?

.const
IDM_TEST equ 1
IDM_HELLO equ 2
IDM_GOODBYE equ 3
IDM_EXIT equ 4

.code
start:
    invoke GetModuleHandle, NULL
    mov hInstance, eax
    invoke GetCommandLine
    mov CommandLine, eax
    invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess, eax

WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov wc.cbSize,SIZEOF WNDCLASSEX
    mov wc.style, CS_HREDRAW or CS_VREDRAW
    mov wc.lpfnWndProc, OFFSET WndProc
    mov wc.cbClsExtra,NULL
    push hInst
    pop wc.hInstance
    mov wc.hbrBackground,COLOR_WINDOW+1
    mov wc.lpszMenuName,OFFSET MenuName
    mov wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon, NULL, IDI_APPLICATION
    mov wc.hIcon,eax
    mov wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    invoke CreateWindowEx,NULL, ADDR ClassName, ADDR AppName,\
    WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
    hInst,NULL
    mov hwnd, eax
    invoke ShowWindow, hwnd, SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    .WHILE TRUE
        invoke GetMessage, ADDR msg, NULL,0,0
        .BREAK .IF(!eax)
        invoke DispatchMessage, ADDR msg
        .ENDW
        mov eax,msg.wParam
        ret
    WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .IF uMsg==WM_DESTROY
    invoke PostQuitMessage, NULL
    .ELSEIF uMsg==WM_COMMAND
        mov eax, wParam
        .IF ax==IDM_TEST
        invoke MessageBox,NULL,ADDR Test_string,OFFSET AppName,MB_OK
        .ELSEIF ax==IDM_HELLO
        invoke MessageBox, NULL, ADDR Hello_string, OFFSET AppName,MB_OK
        .ELSEIF ax==IDM_GOODBYE
        invoke MessageBox,NULL,ADDR Goodbye_string, OFFSET AppName, MB_OK
        .ELSE
        invoke DestroyWindow,hWnd
        .ENDIF
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
        .ENDIF
        xor eax,eax
        ret
    WndProc endp
    end start


I've included my code just in case i've made an obvious error (it's something like 35C here at 12am so forgive me if I've missed something) - obviously I've missed something - just curious on where to start looking.

Muchos gracias!

jj2007

\Masm32\examples\exampl01\comctls\comctls.asm - look for SetMenu

dedndave

in the original example, the menu is supposed to be in the registered class, Jochen

generally, i use LoadMenu, and pass the handle to CreateWindowEx
so, i don't remember the specifics of registering a class with a menu

the info for WNDCLASSEX might help
for lpszMenuName, you might try the ordinal number of the resource, rather than a pointer to a name string
the lpsz method is probably intended for a C compiler

QuotelpszMenuName

    Type: LPCTSTR

    Pointer to a null-terminated character string that specifies the resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu.

dedndave

also, i'm not sure the menu is properly defined in the example RC file
well, i've never done one that way - i always use an ordinal number like this...

#define IDM_MENU 10


IDM_MENU MENU

  POPUP.....


then, in the asm source...

IDM_MENU EQU 10


    mov     wc.lpszMenuName,IDM_MENU


you can use MENU or MENUEX
in the masm32\bin folder is a help file for RC's (rc.hlp i think)
there are also several examples in the masm32\examples folder

jj2007

Quote from: dedndave on February 26, 2016, 12:22:24 AM
in the original example, the menu is supposed to be in the registered class, Jochen

comctls.asm is the original example. And it works, like all examples in \Masm32\examples

btw how do you pass the LoadMenu result to CreateWindowEx?

dedndave

he's using an example from WinAsm or someone   :P

the third from last argument can be a menu handle
i rarely use SetMenu - i did it a couple times when i started playing with windows, i guess

HWND WINAPI CreateWindowEx(
  _In_     DWORD     dwExStyle,
  _In_opt_ LPCTSTR   lpClassName,
  _In_opt_ LPCTSTR   lpWindowName,
  _In_     DWORD     dwStyle,
  _In_     int       x,
  _In_     int       y,
  _In_     int       nWidth,
  _In_     int       nHeight,
  _In_opt_ HWND      hWndParent,
  _In_opt_ HMENU     hMenu,
  _In_opt_ HINSTANCE hInstance,
  _In_opt_ LPVOID    lpParam
);

Anaryl

Quote from: dedndave on February 26, 2016, 12:29:02 AM
also, i'm not sure the menu is properly defined in the example RC file

#define IDM_MENU 10


IDM_MENU MENU

  POPUP.....


then, in the asm source...

IDM_MENU EQU 10


    mov     wc.lpszMenuName,IDM_MENU


you can use MENU or MENUEX
in the masm32\bin folder is a help file for RC's (rc.hlp i think)
there are also several examples in the masm32\examples folder

https://support.microsoft.com/en-us/kb/917607

Just throws me to https://support.microsoft.com/en-us/kb/917607 - goddamnit windows 10.

So anyways I decided to cheat and use the guys example code. It doesn't bring up the menu either! Is this possibly a win10 issue?

Also I caught where I had forget to define FirstMenu MENU in the rc. I'm going to try some example code. I just try and stick with one tutorial tree to avoid getting lost.

http://imgur.com/clyiYqe this is the final result. So I cannot help but feel that I'm missing something here.

[edit] example loads up menus fine - although the code is a bit crowded so there's stuff in there I don't really understand what its doing if you know what I mean - just wanting to start from the very basics then work up.

dedndave


Anaryl

Thanks for that Dave - that looks a bit daunting compared to where I was at, with custom includes and the ilk, but I'll give it a crack.

I think what I'm going to do is basically write a similar application from scratch but copying from your app, the example jj quoted and the tutorial. Hopefully by writing it all myself I can get a better handle on how it all fits together.

jj2007

Attached a template for a modest Masm32 only window.

(note the *.asc file is for use with MasmBasic's RichMasm editor; it contains a resource section that gets exported by the editor during assembly, i.e. you can edit the resources as if they were part of the main source)

Anaryl

Hey just a quick heads up, I opened that comctls example and after looking at the rc I noticed that it too does not have any menus!

Forgive me if I am wrong but this should have a file/help/about menu if I am not mistaken?

http://imgur.com/RQY3eY0

Should there not be the traditional menu bar across the top?

Also thank you guys very much for fast and prompt response - it means a lot. The human interaction element really helps the learning process and is something I often underutilise.

[edit] thanks JJ that one shows the mnu - I share start tearing this one up now.

dedndave


Anaryl

Hey guys I realised I'm a bit of an idiot (well didn't we all) but I think the problem is because I havent actually compiled the resource file!

So I tried using rc.exe and cvtres but they dont seem to have path to the dir where I am building trhe application.

So the file structure looks like A:\masm32\workspace\programfolder

I read there were some issues using the global environment variables for allowing pathing access - that it can interfere with other compilers. So what is the best way to go about compiling the .rc file from rc to .res in this instance (simply trying to use rc. or res gives me bad command or file name). Can i compile the res file in the bin directory or root directory then move it to the workspace folder or will that cause the linker to 'lose sight' of it?

I had a look at this thread here http://masm32.com/board/index.php?topic=327.0

QuoteHi Jannes,

You use the linker, either as a RES file or after converting it to an OBJ file with CVTRES.EXE. For the RES file or the extra OBJ file you need to add it to the object file list on the command line.

Use a command line like this.


\masm32\BIN\Link.exe /SUBSYSTEM:WINDOWS mangled.obj rsrc.obj

But it seems I've got to compile the resource file first ...

Anyways thanks again for the help!

jj2007

If you are using a batch file, name your rc "MyName.rc" and add this:
IF EXIST MyName.rc \masm32\bin\rc MyName.rc

(if you are using RichMasm, the editor will do it for you)

Anaryl

I'm not using a batchfile (is that a makefile?).

Just doing an asm and a .rc


Supposedly there's a way to compile them in visual studio but i got tired of searching through it trying to find out how. I end up getting distracted by learning the tool rather than just learning the task at hand :(