Hi, I have a problem regarding macros. I have an API call that goes something like this



invoke MyAPIName, name1, attribute1, style1, flag1
invoke MyAPIName, name2, attribute2, style2, flag2

So, I created a macro out of this one to reduce the type load.
        

shrAPIname MACRO nme:REQ, attribute:REQ, style:REQ, flag:REQ
irp nName, <nme>
irp nAttribute, <attribute>
irp nStyle, <style>
irp nFlag, <flag>
invoke MyAPIName, &nName, &nAttribute, &nStyle, &nFlag
endm
endm
endm
endm
endm

syntax: shrAPIname <name1, name2>, <attribute1, attribute2>, <style1, style2>, <flag1, flag2>

I know this is wrong. So I need help from you ppl. How do I succesfully produce this code


invoke MyAPIName, name1, attribute1, style1, flag1
invoke MyAPIName, name2, attribute2, style2, flag2


I'm not really a macro guy.

Thanks
Posted on 2002-02-09 20:25:25 by stryker
I keep wanting to reply to this with some answer, but every time i do, i find my self wondering more of *what* its real use will be.

So please, tell me more of how you wish to use this macro. What i mean is, as you have posted, you want to generalize a specific idea (Ie, specific to MyAPIName). So the question comes to mind, what is the api?? This *does* have consideration to some solution strategies Im thinking of. The other is, how many variations of *info* would you place in the parameter of this api. As well, perhaps a more steamlined solution can be found from other angles if i knew this...

NaN
Posted on 2002-02-10 01:49:42 by NaN
NaN,

Funny, I thought it was just the onset of senile decay in my case. :grin:

Regards,

hutch@movsd.com
Posted on 2002-02-10 03:32:36 by hutch--
This thread http://www.asmcommunity.net/board/showthread.php?threadid=3480 will hint something about this API. This macro thingy also address to my other project that involves the call of AppendMenu. Since AppendMenu, may be repeated a few times, I wanted to create a macro out of it to reduce the type load.

The only solution, I can think of is to create a whole new assembler that handles this job. I tried every possible solution I can think of under MASM and failed :(

Funny, I thought it was just the onset of senile decay in my case.

Ha! Ha! Ha! :grin: I'm way too young for my age. I'm still in college!...PSYCHIC feeling: You thought I was drunk or lost my sanity...Bzztt!!! :grin:

But anyway thanks for trying to help! :grin:
Posted on 2002-02-10 10:46:02 by stryker
Hmmm, this is still not alot of info, but its a start.

If your intending on using AppendMenu to build up your pop up menu's or what not, with say alot of string handles:

You could use a for loop (since it will UNROLL rather than loop when compiled).

AddMenuStrings MACRO StartID:REQ, stringlist:VARARG

LOCAL Cid

Cid = StartID
for arg,<stringlist>
invoke AppendMenu, hMenu, MF_POPUP or MF_STRING, Cid, arg
Cid = Cid +1
ENDM

ENDM


This assumes that hMenu is constant, as well as they type of data being passed, but does allow you to add multiple string references and a starting ID location:




String1 db "Option 1",0
String2 db "option 2",0
String3 db "Option 3",0
...
String9 db "Option 9",0

AddMenuStrings 5000, offset String1, Offset String2, ... ,... , offset String9


and thus add 9 strings to the fixed menu, starting from the passes ID val 5000 -> 5008. (9 strings).

You can also modify this macro a bit more to make the the menu handle flexible etc. As well, you can make a few varients of this macro for the different types of items to append to the menu.

This is not an exact solution, but its one idea (but then again, i still dont really know how you wish to use the origional idea ~ in code ).

Hope you it helps..
:alright:
NaN
Posted on 2002-02-10 18:16:06 by NaN
Here's a code snippet from one of my programs.




[size=9]

cMenu MACRO hCMnu:REQ
call CreateMenu
mov hCMnu, eax
ENDM

cPMenu MACRO hCPMnu:REQ
FOR cP, <hCPMnu>
call CreatePopupMenu
mov cP, eax
ENDM
ENDM

aMnuItem MACRO hMnu:REQ, uStyle:REQ, uID:REQ, uStr:VARARG
IRP mnu, <hMnu>

;if mnu is on the second element, style also will start on the second element

IRP style, <uStyle>

;if mnu is on the second element, id also will start on the second element

IRP id, <uID>

;if mnu is on the second element, str also will start on the second element

IRP str, <uStr>

invoke AppendMenu, &mnu, &style, &id, &str

;Need something here to end the loop

ENDM

;Need something here to end the loop

ENDM

;Need something here to end the loop

ENDM

;mnu will keep track on which element we are now

ENDM
ENDM

cMenu mHandle
cPMenu <pOptHandle, pOptpRdx>
invoke AppendMenu, mHandle, MF_POPUP, pOptHandle, OFFSET pOptions
invoke AppendMenu, pOptHandle, MF_STRING, IDCTRL_GRN, OFFSET sGRN
invoke AppendMenu, pOptHandle, MF_POPUP, pOptpRdx, OFFSET pHRadixSort
invoke AppendMenu, pOptpRdx, MF_STRING, IDCTRL_RDX_DESC, OFFSET sDesc
invoke AppendMenu, pOptpRdx, MF_STRING, IDCTRL_RDX_ASC, OFFSET sAsc
invoke AppendMenu, pOptHandle, MF_SEPARATOR, NULL, NULL
invoke AppendMenu, pOptHandle, MF_STRING, IDCTRL_EXT, OFFSET sExit

;Actually, what I wanted was to create this kind of macro where
;I can use it something like this:

aMnuItem <mHandle, pOptHandle, pOptHandle, pOptpRdx, pOptpRdx, pOptHandle, pOptHandle>,
<MF_POPUP, MF_STRING, ...>, <...>, <...>
[/size]



I know this is possible if I can just control the "for loop". I mean I can control where it ends and where it starts. If that is possible then the macro code on the first thread will work perfectly with slight modifications. I guess there is no such way in MASM. :(

NaN, your macro code is nice.
Posted on 2002-02-10 21:13:13 by stryker
Stop thinking the multiple nestings will do the job, It wont work. If it did work you would get *every* combination of the parameters invoked, not all the param1's followed by the param2's....

Seeing your code make its clearer. I sugest that you use a macro set up that is more inutitive to what you want to have happen.



$invoke MACRO args:VARARG
invoke &args
ENDM <eax>
ENDM

Append_Menu MACRO TheMenu:REQ, appendlist:REQ
for arg,<appendlist>
invoke AppendMenu, TheMenu, &arg
ENDM
ENDM


.code


mov mHandle, $invoke(CreateMenu)
mov pOptHandle, $invoke( CreatePopupMenu )
mov pOptpRdx, $invoke( CreatePopupMenu )

Append_Menu mHandle, < MF_POPUP, pOptHandle, OFFSET pOptions >

Append_Menu pOptpRdx, < <MF_STRING, IDCTRL_RDX_DESC, OFFSET sDesc>, \
<MF_STRING, IDCTRL_RDX_ASC, OFFSET sAsc> >

Append_Menu pOptHandle, < <MF_STRING, IDCTRL_GRN, OFFSET sGRN>, \
<MF_POPUP, pOptpRdx, OFFSET pHRadixSort>, \
<MF_SEPARATOR, NULL, NULL>, \
<MF_STRING, IDCTRL_EXT, OFFSET sExit> >



These will produce the above code that you posted. I dont agree with the use of a MACRO for CreateMenu and CreatePopupMenu. They are too specific for a macro in my opinion. This is why i replaced them with the $invoke macro, as it is more general and can be used for other things.

Anywho.. hope you like..
:alright:
NaN
Posted on 2002-02-10 22:57:34 by NaN
Hey! It's working :) I thought it was impossible. I think I need to take macro 101. Thanks NaN :alright:

I change some macro code to make it work!!! Thanks :)




[size=12]
$invoke MACRO args:VARARG
invoke &args
EXITM <eax>
ENDM
[/size]

Posted on 2002-02-10 23:29:55 by stryker
Doh! My Typo... :)

Glad you like... I think i will add this to my web-page.. I think it can be quite handy.. (( The idea will be your credit tho :) ))

PS: Macro 101 can be found in chapter 9 of the MASM programming manual... (Check out BitRake's page, if you dont have it).

NaN
Posted on 2002-02-11 00:10:05 by NaN
To anyone who has the MASM programming manual:

Seems to me BitRake has remove the d/l for the MASM programming manual. If it's ok for anyone who would like to send me the manuals that would be great(just send it through attachment... egi12@yahoo.com). If that is not possible due to legality issues, that's ok.

Thanks!!!
Posted on 2002-02-11 13:40:06 by stryker
Look at the links at the bottom of this thread:
http://www.asmcommunity.net/board/index.php?topic=421&highlight=%2AManual%2A+MASM

I was unable to find that wonderful PDF I always have open - a single file of MASM6.1 doc. I know there is a link on the board.
Posted on 2002-02-11 14:11:18 by bitRAKE
Thanks You!!!! Thank You!!!! :alright: The ones I have are in .doc files and only up to chapter 7. I got the pdf file... :cool: It's actually ~2++ mb
Posted on 2002-02-11 15:02:40 by stryker
I turned into a macro freak: In addition to NaN's macro code, I changed it into a more generalized macro.




[size=12]
uCall MACRO APICall:REQ, Attr:REQ
FOR Args, <Attr>
invoke APICall, &Args
ENDM
ENDM

uCall AppendMenu, <<mHandle, MF_POPUP, pOptHandle, OFFSET pOptions>>
uCall AppendMenu, <<pOptpRdx, MF_STRING, IDCTRL_RDX_DESC, OFFSET sDesc>, \
<pOptpRdx, MF_STRING, IDCTRL_RDX_ASC, OFFSET sAsc>>
uCall AppendMenu, <<pOptHandle, MF_STRING, IDCTRL_GRN, OFFSET sGRN>, \
<pOptHandle, MF_POPUP, pOptpRdx, OFFSET pHRadixSort>, \
<pOptHandle, MF_SEPARATOR, NULL, NULL>, \
<pOptHandle, MF_STRING, IDCTRL_EXT, OFFSET sExit>>
[/size]



By using this macro, you can call any win32 API function that are usually repeated on your program, in this case :: AppendMenu. I know it's "cheap" I'll polish this macro once I graduate from macro 101.

One problem though, this one doesn't work on an API function that doesn't have any parameter E.G. CreateMenu. So I need to do some conditional compilation(IF...) - I'll add this feature soon.

And by the way, the code above could be changed to one call of the macro but MASM complains that the line is too long. Anyway, maybe I'll add some error checking to it.

Happy Coding!!!
Posted on 2002-02-11 18:20:36 by stryker


uCall MACRO APICall:REQ, Attr
IFNB <Attr>
FOR Args, <Attr>
invoke APICall, &Args
ENDM
ELSE
invoke APICall
exitm <eax>
ENDIF
ENDM


: Today i woke up and realized i was asleep behind the keyboard :) , This is untesetd, but should act like $invoke if no other params is given, otherwise, it will carry out the multiplicity your asking for:

uCall ThisAPI, < <...., ...> , <.. /// >>

or

mov StoreIt, uCall( TheAPI )

Anywho, Enjoy.... ;)
:alright:
NaN
Posted on 2002-02-12 10:32:24 by NaN
It took me a long time to look at your code, NaN. I changed some parts of the code to make it work:




[size=12]
uCall MACRO APICall:REQ, Attr
IFNB <Attr>
FOR Args, <Attr>
invoke APICall, &Args
ENDM
ELSE
invoke APICall

;MASM complains on the EXITM<eax> dunno why?

ENDIF
ENDM

uCall CreateMenu
mov mHandle, eax
...
uCall AppendMenu, <<mHandle, MF_POPUP, pOptHandle, OFFSET pOptions>>
...
[/size]



Thanks again!!!
Posted on 2002-02-13 21:49:44 by stryker
No probs, i didnt test it...

Its because im trying to exit the macro from two points... EXITM should be the last statement... Would be cool if it worked tho..

Perhaps "Luke" could use the "force" and suggest a method :grin:

NaN
Posted on 2002-02-13 22:21:30 by NaN
You should be able to use mulitple EXITM.
Assemble this and look at the output:
fib MACRO y:REQ

LOCAL a,b,e
IF y LE 1
EXITM <1>
ELSE
e = y
a = fib(e/2)
b = fib(e/2 - 1)
IF (y MOD 2) EQ 1
EXITM %(a * (a + 2 * b))
ELSE
EXITM %(a*a + b*b)
ENDIF
ENDIF
ENDM

; My favorite sequence ;)
i TEXTEQU fib(46)
%ECHO i
Scary as it may be, you can even do this:
l33t MACRO dude:REQ

EXITM dude
MASM bails out before it even gets to this line!
So this isn't an error or anything as long
as the next line exists
ENDM
You could even document your macros like this:
VeryComplexMacro MACRO a:REQ,b:REQ

;; do some very complex stuff here...
EXITM
Explain all that complex stuff you did above :tongue:
ENDM
Posted on 2002-02-13 23:18:33 by bitRAKE
Hmmm... My error...

Wonder why it wouldnt work then... didnt figure out any solution, but as i see it, if MASM realized there is *any* EXITM in the macro, then it automatically assumes the macro to be "in line" type. So it generates the error when the macro is used as the only "statement" on a line, as it assumes there must be some operation preceeding it.

THis is just my theory tho, did 10min of testing...

NaN
Posted on 2002-02-14 00:41:46 by NaN
Ooops, my mistake. Actually EXITM works perfectly(I misread the line numbers, the error was on the .asm file not inside the macro) but




[size=9]
mov mHandle, uCall(CreateMenu)
mov pOptHandle, uCall(CreateMenu)
mov pOptpRdx, uCall(CreateMenu)

;This is the start of the problem not EXITM
;It says: syntax error, i believe it can't recognize the parameters...

uCall AppendMenu, <<mHandle, MF_POPUP, pOptHandle, OFFSET pOptions>>[/size]



The issue here isn't EXITM but the macro parameters itself(I hope i'm right). I don't know why but I'll try to fix this up. The only stable solution is the previous macro but you have to do 2 lines of code(I want only 1). Sorry for the misundertanding, I must have incinerated a couple of brain cells. :)

Anyway, I'm happy about it!!!
Posted on 2002-02-14 00:42:05 by stryker
Ahhh figured it out... results arnt too good tho..


MASM "WANTS" a "(" and ")" around the params if EXITM is used anywhere in the macro ~ unconditionally.

The bummer is, for you uses, this greatly restricts the info you pass, as you have to provide it all in one line!

     mov edx, uCall( CreateMenu )  

uCall( AppendMenu, <<TheMenu,1,2,3>,<TheMenu,10,11,12>,<TheMenu,250, 251, 252> > )


This works with my origional macro (previous page)...

     mov edx, uCall( CreateMenu )  

uCall( AppendMenu, <<TheMenu,1,2,3>, \
<TheMenu,10,11,12>,<TheMenu,250, 251, 252> > )


This fails! BitRake, any sugestions how to get around this ( ) issue??

NaN
Posted on 2002-02-14 00:56:48 by NaN