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
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):
(http://www.webalice.it/jj2006/pics/SysLinkDemo.png)
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
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.
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
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 (http://masm32.com/board/index.php?topic=5314.0) ;)
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
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, ...)
I have a simple solution, use numbers, no conversion needed.
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
@John
poasm have a CINCLUDE for that, not a bad idea ?
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.
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 (http://masm32.com/board/index.php?topic=94.0)), the Enum macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1016) 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
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?
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
Quote from: Biterider on November 24, 2018, 06:42:46 PMWhat 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.
If you have a crispy example of an asm+rc pair where this matters, please post it. Right now I have no time at all, but it shouldn't take more than ten minutes to adapt my preprocessor for parsing also the symbolic equates. Compilers do that all the time.
Quote from: jimg on November 24, 2018, 03:49:54 PM
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?
search -manifest:embed link.exe commandline option for latest linkers.
OPTION DOTNAME
.drectve SEGMENT INFO DISCARD
db "-subsystem:console "
db 34,"-manifestdependency:type=",39,"Win32",39
db " name=",39,"Microsoft.Windows.Common-Controls",39
db " version=",39,"6.0.0.0",39
db " processorArchitecture=",39,"*",39
db " publicKeyToken=",39,"6595b64144ccf1df",39
db " language=",39,"*",39,34
;db " -manifest:embed "
.drectve ENDS
Quote from: Biterider on November 24, 2018, 06:42:46 PMEQUs with symbolic content can not be converted, since the symbols do not represent their actual value in the code.
Just checked my tool in Reply #7, and surprise surprise, this works:
source.asm:
IDM_FILE_OPEN EQU 40001
IDM_FILE_SAVE EQU IDM_FILE_OPEN+9
source.rc, before preprocessor ran:
#define IDM_FILE_OPEN ?
#define IDM_FILE_SAVE ?
source.rc processed:
#define IDM_FILE_OPEN 40001
#define IDM_FILE_SAVE IDM_FILE_OPEN+9
... and that works fine with rc.exe :t
Quote from: TimoVJL on November 24, 2018, 11:11:07 PM
Quote from: jimg on November 24, 2018, 03:49:54 PM
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?
search -manifest:embed link.exe commandline option for latest linkers.
Thanks! I'm still using tired old link 5 from 1998. I look into getting a newer linker :)
Quote from: jimg on November 24, 2018, 03:49:54 PMI have searched in vain how to get around manifests, how do you do it without a resource file?
Jim,
It's not impossible but impractical, see the Weird problem with UpdateResource (http://masm32.com/board/index.php?topic=5824.0) thread. You can indeed add a resource to an existing exe, but it requires elevation, i.e. you need to insert the admin password every time you build a project as a normal user. At that point, having a standard manifest.rc is much easier.