Hey All,
Been playing around with Macros and coming from HLA, certain syntax and the way macros look just does sit right with me. ;-) So I am trying to learn and see if I can remove, or design a macro that works like I would want. hehe
Anyway, here is some macros I wrote that do work.
; Macros for creating a Message Map of handlers
M_BEGIN_MESSAGE_MAP MACRO map_name:REQ
ECHO map_name
map_name dd 0ffffh
dd 0ffffh
dd 0ffffh
dd 0ffffh
dq 0h
dq 0h
ENDM
M_END_MESSAGE_MAP MACRO
dd 0h
dd 0h
dd 0h
dd 0h
dq 0h
dq 0h
ENDM
M_MSGMAP_INTERNAL MACRO wm:req, cn:req, idF:req, idL:req, fn:req
ECHO wm, cn, idF, idL, fn, 0h
dd wm
dd cn
dd idF
dd idL
dq fn
dq 0h
ENDM
M_COMMAND_MSG MACRO id:req, fn:req
M_MSGMAP_INTERNAL WM_COMMAND, CN_COMMAND, id, id, fn
ENDM
Syntax to use these macros looks like the following:
M_BEGIN_MESSAGE_MAP Application
M_COMMAND_MSG IDM_EXIT, testFunc
M_UPDATE_COMMAND_UI_MSG IDM_FILE_SAVE, testFunc
M_UPDATE_COMMAND_UI_MSG IDM_FILE_SAVEAS, testFunc
M_WINDOW_MESSAGE WM_CREATE, testFunc
M_WINDOW_MESSAGE WM_PAINT, testFunc
M_WINDOW_MESSAGE WM_DESTROY, testFunc
M_WINDOW_MESSAGE WM_NCDESTROY, testFunc
M_END_MESSAGE_MAP
Now, this work beautifully, creates my array (based on the name I give -- ie: Application), and fills in the array with values at compile time. So, in my .data section, I have an array named Application with values.
What I am hoping to achieve is modify the macros to look like the following:
M_BEGIN_MESSAGE_MAP(Application)
M_COMMAND_MSG(IDM_EXIT, testFunc)
M_UPDATE_COMMAND_UI_MSG(IDM_FILE_SAVE, testFunc)
M_UPDATE_COMMAND_UI_MSG(IDM_FILE_SAVEAS, testFunc)
M_WINDOW_MESSAGE(WM_CREATE, testFunc)
M_WINDOW_MESSAGE(WM_PAINT, testFunc)
M_WINDOW_MESSAGE(WM_DESTROY, testFunc)
M_WINDOW_MESSAGE(WM_NCDESTROY, testFunc)
M_END_MESSAGE_MAP()
Notice the parenthesis around the parameters to macro. These get inserted into the array and cause all kind of compile problems.
So, is there a way to remove those parenthesis from, I am assuming, argument text strings, or be able to strip any type of char from an argument?
Relvinian
I've noticed that some people instead of
.if eax
write
.if (eax!=0)
It gets assembled, of course, but what is the added value of adding noise? Your macros work without, it seems ::)
JJ2007,
Quote from: jj2007 on March 15, 2017, 08:06:25 PM
I've noticed that some people instead of
.if eax
write
.if (eax!=0)
It gets assembled, of course, but what is the added value of adding noise? Your macros work without, it seems ::)
I think it is more of a personal preference, especially if you work with multiple languages and syntax.
For example, when working with pointers in C / C++, you always use something like:
*var -or- *(var)
and variables pointing to structure members are along the lines of:
myVar->nCode = 10;
But with languages like C#, Java, and others. There are no such things as pointers. Everything is "." oriented. So, you would see something like:
myVar.nCode = 10
So, for some, wrapping parenthesis around statements or so forth, is more "mathematical" logical to emphasis ordering.
x = 5 * y + 10
Some can read that just fine. Others prefer the following:
x = (5 * y) + 10
Both are 100% mathematically correct in the way the value is determined.
Relvinian
Transform your macros into function-like macros that returns nothing. For that make sure all paths in your macro ends with EXITM <>.
; Macros for creating a Message Map of handlers
M_BEGIN_MESSAGE_MAP MACRO map_name:REQ
ECHO map_name
map_name dd 0ffffh
dd 0ffffh
dd 0ffffh
dd 0ffffh
dq 0h
dq 0h
EXITM <>
ENDM
M_END_MESSAGE_MAP MACRO
dd 0h
dd 0h
dd 0h
dd 0h
dq 0h
dq 0h
EXITM <>
ENDM
M_MSGMAP_INTERNAL MACRO wm:req, cn:req, idF:req, idL:req, fn:req
ECHO wm, cn, idF, idL, fn, 0h
dd wm
dd cn
dd idF
dd idL
dq fn
dq 0h
ENDM
M_COMMAND_MSG MACRO id:req, fn:req
M_MSGMAP_INTERNAL WM_COMMAND, CN_COMMAND, id, id, fn
EXITM <>
ENDM
qWord was a bit faster, he posted while I still was testing my example:
include \masm32\include\masm32rt.inc
M_COMMAND_MSG MACRO id:req, fn:req
Local tmp$
tmp$ CATSTR <Hi. You passed me [>, <id>, <] and [>, <fn>, <]>
% echo tmp$ ; in your output window: Hi. You passed me [IDM_EXIT] and [testFunc]
; M_MSGMAP_INTERNAL WM_COMMAND, CN_COMMAND, id, id, fn
EXITM <>
ENDM
.code
start:
M_COMMAND_MSG(IDM_EXIT, testFunc)
.err ; force an error to avoid running the program
inkey "ok?"
exit
end start
MasmBasic void (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1213) uses the same exitm <> technique.
Still, IMHO there is no need to add noise to an elegant language like assembler.
jj2007 and qWord,
Thank you for the help and example. Now, from what I see, can't test until i get home to try it out, that you can either add in the parenthesis -or- leave them off and the results will be the same?
That way, I am guessing you can have the best of both worlds depending on your preference. ie: With parenthesis or without when setting up the table. If so, this is just exactly what I am looking for.
The reason I wanted this, is because I have been working on my old library that was written over 10 years ago for only 32-bit, ANSI & UNICODE. Now I am adding in 64-bit code, plus working on a new personal project, an IDE that mimics Visual Studio (for ASM only), but wanted to give end-users the ability to code in styles they prefer.
Thanks again you two!
Relvinian
Quote from: Relvinian on March 16, 2017, 03:39:18 AMyou can either add in the parenthesis -or- leave them off and the results will be the same?
No. Using my example above:
M_COMMAND_MSG(IDM_EXIT, testFunc) ; OK
M_COMMAND_MSG IDM_EXIT, testFunc ; syntax error
Macros can be standalone
or they can return something (including an empty string via exitm <>), but not both.