News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Sharing values

Started by Biterider, November 14, 2018, 01:56:15 AM

Previous topic - Next topic

Biterider

Hi
Has somebody a practical solution to share values between our asm files and the resource compiler?
For example, we have some ID values for the menus which have to be copied tot he .rc file prepending #define to each item.
Biterider

jj2007

This is indeed a major design flaw of the Masm tool chain. You could use special variables, such as _rcEdit=100, _rcButton=101, then parse the asm file for those lines and prepend them to the *.rc file.

Personally, I keep the asm and rc part in a single source, which makes find & replace easier, as shown below (the rc file gets created during the build process):

Biterider

Hi
It seems that other assemblers have the same problem
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3529.html

Thinking about it, a possible solution could be that the assembler (UASM) writes text to a user defined file, like echo does to the STDOUT. This way, using a macro and this special feature we can equate the value for our assembler prog and emit the shared information for the rc.
It requires some extra work on UASM to open, write and close the desired file.  :icon_cool:

Biterider

jj2007

Gimme a pair of asm and rc files, and I'll do a test. I don't think it's a good idea to burden the assembler with this task.

Biterider

Hi
While looking for various alternatives to solve this problem, I've found that ML & UASM differ slightly in the output to STDOUT and STDERR. For some strange reason, ML writes the logo to STDERR while the echo and the .err output to STDOUT.
UASM outputs all to STDOUT.

Using the commadline option /nologo on ML, they produce the same result.

This means that the second system stream is not really used yet and can be used to create the desired file. What we need is a command like .out (analogous to .err) to write to STRERR.

It should not be that hard.

Biterider

jj2007

Indeed, it's not that hard. Attached two projects:
1. \Masm32\examples\exampl01\showdib\showdib2J.asc is the modified version of the showdib2.asm in that folder.
2. DefineRcIDs is the preprocessor that extracts the IDs from the *.asm file and inserts them into the *.rc file

In the asm source, you have:
- a pragma to invoke the preprocessor:
if 0
  OPT_PreProcess DefineRcIDs.exe ; and here is the magic proggie!
endif


- the resource section (shortened):

Rsrc
#define IDM_FILE_OPEN           ?          <<<<<<<<<<<<<< the trick <<<<<<<<<<<<<
#define IDM_SHOW_NORMAL         ?
...
// Accelerator

SHOWDIB2 ACCELERATORS DISCARDABLE
{
"C",            IDM_EDIT_COPY,          VIRTKEY, CONTROL, NOINVERT
"O",            IDM_FILE_OPEN,          VIRTKEY, CONTROL, NOINVERT
"P",            IDM_FILE_PRINT,         VIRTKEY, CONTROL, NOINVERT
"S",            IDM_FILE_SAVE,          VIRTKEY, CONTROL, NOINVERT
VK_DELETE,      IDM_EDIT_DELETE,        VIRTKEY,          NOINVERT
"X",            IDM_EDIT_CUT,           VIRTKEY, CONTROL, NOINVERT
}
Rsrc


Any change of the ID in the main *.asm section gets immediately transferred to the *.rc file.

Works like a charm with RichMasm ;)

Biterider

Hi JJ
Thanks for helping to solve this problem.  :t
Your approach is correct, but I was looking for a more flexible solution than a tailored solution for this case.
Imagine if it would be possible to generate a file, which we can create on the fly... It would be possible to create custom listings, extract information from converted .h files, IDs and other stuff for .rc files, GUIDs, support for TypeLibs, xml files, etc.

Having the chance to write to one of the unused system stream is always better than nothing.  ;)

Biterider

jj2007

My demo is indeed limited to the specific task "grab the IDs from the main asm file".

But you can extend it to any other use case that requires inserting variables into the files needed for the build process. Asking the assembler to do that is problematic because there are many 'unspecific' cases to care for.

Here is a version that doesn't require RichMasm; just extract these three files to \Masm32\examples\exampl01\showdib\ ...
\Masm32\examples\exampl01\showdib\DefineRcIDs.exe the preprocessor
\Masm32\examples\exampl01\showdib\makeWithPreprocessing.bat makefile
\Masm32\examples\exampl01\showdib\rsrcWithQMs.rc modified rc file with question marks

... then run makeWithPreprocessing.bat  8)

The source of the preprocessor is also included (*.asc is RTF and opens in RichMasm, Wordpad, MS Word, ...)

hutch--

I have a simple solution, use numbers, no conversion needed.

johnsa


You could put the values as equates in an INC file, and just convert them to defines in another file to include in the rsrc with a script ?

IDM_LABEL equ 0x0001

becomes

#define IDM_LABEL 0x0001


TimoVJL

@John
poasm have a CINCLUDE for that, not a bad idea ?
May the source be with you

hutch--

This has always made me laugh, because Microsoft long ago started the habit of attaching equates to numeric values which in many instances was OK when it came to massively long lists of numbers, it has been robotically applied to individual applications which means two (2) extra steps are usually taken to connect resource identification to code in the application. It not only involves a fair bit of extra work but it loses the intuitive use of number sequences.

Now for example if you have a lot buttons on an interface, using equates means you have to try and invent enough unique names to match the number of buttons where if you use the immediate numeric identification, you are free of all of this clutter.

invoke GetDlgItem,hWin,50    ; the first button
mov btn1, rax

If you reserve 50 to whatever number range you require, you only have to increment the resource ID instead of having to mess around with equates out of a RC file and another set of equates for the source code file.

An RC script is compiled into a RES file which is not in the same format as an OBJ file and it requires one of the resource API function calls to access the resource AFTER it has been linked into the final exe/dll by the linker.

jj2007

I must confess that I rarely use resource files - you can do most things (menus, unicode strings etc) better in the main source.
But if needed, the tool in Reply #7 can perfectly serve OP's request to grab IDs from the main code and insert them in the *.rc file. No MasmBasic required to run it.

Another option (and this one does require MasmBasic version 24.11.2018), the Enum macro can now take a *n argument as follows:

  Enum 110:butn*10, edits*5              ; create a bunch of IDs, starting with the value 110
  PrintLine Str$("Button0=%i", butn0)
  PrintLine Str$("Button9=%i", butn9)
  PrintLine Str$("Edit0=%i", edits0)
  PrintLine Str$("Edit4=%i", edits4)


Output:
Button0=110
Button9=119
Edit0=120
Edit4=124

jimg

Quote from: jj2007 on November 24, 2018, 02:26:00 PM
I must confess that I rarely use resource files - you can do most things (menus, unicode strings etc) better in the main source.

Not to hijack the thread, but...   I also seldom use resource files, but I have searched in vain how to get around manifests, how do you do it without a resource file?

Biterider

Hello
I went the suggested way of the script and wrote a few lines. It works well and covers most cases.
Basically it is, what JJ did.  :t

@echo off
REM Usage: inc2rc SrcFile.inc DstFile.rc
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION

echo inc2rc conversion...

if [%~1]==[] (
  echo inc2rc error: missing argument
) else (
  set SrcFile=%~1
  set SrcFileNoExt=!SrcFile:~0,-4!
 
  if [%~2]==[] (
    set DstFile=!SrcFileNoExt!.rc
  ) else (
    set DstFile=%~2
  )
  echo //Data imported from !SrcFile!; %Date%, %Time%>!DstFile!
  echo.>>!DstFile!

  for /f "tokens=1,2,*" %%A in (!SrcFile!) do (
    if "%%B" == "=" (
      echo #define %%A %%C>>!DstFile!
    ) else (
      set Text=%%C
      set FirstChar=!Text:~0,1!
      if "!FirstChar!" == "<" (set Text="!Text:~1,-1!")
      if "%%B" == "equ" (
        echo #define %%A !Text!>>!DstFile!
      ) else (
        if "%%B" == "textequ" (
          echo #define %%A !Text!>>!DstFile!
        ) else (
          echo inc2rc conversion failed on %1: %%A %%B %%C>>Make.txt
        )
      )
    )
  )
)


What I've noticed, however, is that, for example, EQUs with symbolic content can not be converted, since the symbols do not represent their actual value in the code.

ID_MYWND  equ  MYWND_ID

Otherwise, this approach works well.  ;)

A completely different possibility would be to write into the resource section itself. AFAIK fasm does it that way.  :idea:

Biterider