Hi,

I am trying to learn how com is working. I can't understand which condition telling if the SDWORD should be or not. For example Get/Put ActivePrinter and Caption have no parameters and a "return value" BSTR. But why is SDWORD present in case of ActivePrinter but not in case of Caption? I have not found any pattern. And what value should SDWORD have (0?)?

VB code

Dim EXC As Excel.Application
Dim x as String
Set EXC = CreateObject("Excel.Application")

x = EXC.ActivePrinter
EXC.ActivePrinter = "printer"

corresponds to assembler

STDMETHOD get_ActivePrinter , :SDWORD,:ptr BSTR
STDMETHOD put_ActivePrinter , :SDWORD,:BSTR

and VB code

x = EXC.Caption
EXC.Caption = "caption"

corresponds to assembler

STDMETHOD get_Caption , :ptr BSTR
STDMETHOD put_Caption , :BSTR

The VB code for caption and activeprinter are build-up on the same manner, but not assembler code. I would be very grateful if somebody could explain this to me.

Best regards
Posted on 2004-04-15 17:15:47 by minor28
If i remember correctly this is the LCID parameter. Its a 'hidden' parameter that is used by VB/C++ and other HLLs to describle the OS language. For english i believe the value is 1033, however 0 seems to work as well.

Looking at ComView, its setup to pass 800h in... (in the Options.General tab).

Hope this helps.
Regards,
:NaN:
Posted on 2004-04-15 22:50:58 by NaN
Hi minor28,

the attribute - for parameters - is described in MIDL language reference.
it is always the last parameter, with the exception of a parameter.

Japheth
Posted on 2004-04-16 02:33:26 by japheth
Thanks NAN and japheth.

Ok I understand "what" but not "how". The reason for asking is that the ComView and includefiles is somewhat hard to apply to practise with my limited knowledge, though the function is working fine.

My idea is to create include files to each Asm project with only parts necessary to the project. I am working with RadAsm which gives the possibility to help information as tooltips. To achieve this I am creating a RadAsm tool. With the tool I create the include files (in Excel example) ExcelC.inc with constants, ExcelF.inc with functions (as struct with dd ? pointers). According to the need I can add functions and constants to the include files.

Clicking on an item in column 2 opens a dialog with editable asm code to paste into the project. Now I am working with the function parameters which is the reason for my question on the hidden LCID parameter.

I have not found any method to identify which function has the LCID parameter. I attach the tool (it is written in VB6.0) and would be glad to hear your comments.

Best regard
Posted on 2004-04-17 04:37:44 by minor28
Hi minor28,

finding functions with lcid parameter requires in fact some thorough understanding of IDispatch and automation, so I wont describe it here.

But I'm able to tell how to navigate with comview to find such infos

An example:

1. open the excel type library.
2. get dispatch interface _Workbook
3. select tab "interfaces"
4. dblclick the _Workbook entry (will open another typeinfo dialog)
5. now property "Author" for example has the lcid parameter

what makes this stuff so complicated is that for dual interfaces there exist in fact 2 typeinfos,
one describes the dispatchable part, the other describes the vtable part. Only the "vtable" typeinfo
will have "lcid" and "retval" parameters, all functions in such typeinfos return a HRESULT and it is this
typeinfo that is used by comview to generate include files.

Japheth
Posted on 2004-04-17 09:57:59 by japheth
Thanks japheth for your hints,

I have dug a little deeper and now I know how to find out if an object has a lcid parameter.

Regards
Posted on 2004-04-19 10:58:44 by minor28
Interesting tool there... I hope you share it when your finished. :alright:


Regards,
:NaN:
Posted on 2004-04-19 17:12:35 by NaN
Hi

yes, I will share it but the tool is VB. Perhaps I will convert it to asm later. Having the tool it shouldn't be to difficult i hope.

Some Excel functions have a lot of parameters, up to 30. Most of them are optional. In normally VB coding you can disregard these parameters but not in assembler. To handle all these parameters I need some macro writing. In fact I don't like macros but I think it is nessesary here. I have succeeded to write a macro pushing all what needs for a disregarded optional parameter (NoParam).

Could sombody help me with macro "Params". The following example shows how I intend to generate code to open an existing workbook.
mov eax,pWorkbooks

mov edx,[eax]
push offset pWorkbook
push 0
;Params( Filename, [UpdateLinks], [ReadOnly], [Format], [Password], [WriteResPassword], [IgnoreReadOnlyRecommended], [Origin], [Delimiter], [Editable], [Notify], [Converter], [AddToMru])
Params( :VT_BSTR, NoParam, NoParam, NoParam, NoParam, NoParam, NoParam, NoParam, NoParam, NoParam, NoParam, NoParam, NoParam)
push pWorkbooks
call dword ptr [edx].Workbooks._Open

As you can see there are 13 parameters excluding lcid parameter and return paramet. The commented line will also be generated to simplify recognization.

How do I write a macro to handle the parameters in reverse order. All is about pushing a lot stuff on the stack. I would be grateful.

Attached is the previous Com.exe and a Com.mdb. The database will hold code snippets and macros.

Best regards
Posted on 2004-04-20 10:04:09 by minor28
I didnt test this, but this should work:

DUMB_TEST MACRO FileName, args:VARARG

IFNB <args>
pargs CATSTR <!<>, <args>, <!>>
%FOR arg, @ArgRev(pargs)
push arg
ENDM
call FileName
ENDM



Regards,
:NaN:
Posted on 2004-04-20 11:32:34 by NaN
Thanks NAN,

But I suppose I didn't make it clear. Params is the macro that I can't write and the arguments list is the function parameters. The function parameters can vary from function to function both in amount and type. In this example FileName is a pointer to the workbook to open. The rest of the parameters are VARIANTs. NoParam is a macro I have written.
NoParam macro

LOCAL var
.data
var VARIANT <>
.code
mov var.vt,VT_ERROR
mov var.scode,DISP_E_PARAMNOTFOUND
push dword ptr [var+0ch]
push dword ptr [var+8]
push dword ptr [var+4]
push dword ptr [var]
endm


So a VARIANT parameter requires four pushes. This code opens the selected workbook i.e FileName="Book1.xls"
	invoke MultiByteToWideChar,CP_ACP,0,addr szWorkbook,-1,addr lpWideCharStr,\

sizeof lpWideCharStr
invoke SysAllocString,addr lpWideCharStr
mov pWideAllocStr,eax
mov eax,pWorkbooks
mov edx,[eax]
push offset pWorkbook
push 0
[color=red]mov ecx,12
@@:
NoParam
loop @B
push pWideAllocStr[/color] 'Book1.xls
push pWorkbooks
call dword ptr [edx].Workbooks._Open

It's the red lines I want to replace with a macro. I have tested @argrev but I always get an compile error.

Regards
Posted on 2004-04-20 13:36:38 by minor28
Perhaps your looking for something like this then?:
NULL_PUSH   MACRO Num:=<1>

LOCAL a1, a2, a3
a1 equ <Num>
a2 = 0
while a1 ne a2
push 00000000h
push 80020004h
push 00000000h
push 0000000Ah
a2 = a2 + 1
endm
endm


Used as:

	invoke MultiByteToWideChar,CP_ACP,0,addr szWorkbook,-1,addr lpWideCharStr,\

sizeof lpWideCharStr
invoke SysAllocString,addr lpWideCharStr
mov pWideAllocStr,eax
mov eax,pWorkbooks
mov edx,[eax]
push offset pWorkbook
push 0
NULL_PUSH 12
push pWideAllocStr 'Book1.xls
push pWorkbooks
call dword ptr [edx].Workbooks._Open


I havent tested this, but it should work for you.
PS: Macros are worth embracing ;)
:alright:
:NaN:
Posted on 2004-04-20 23:48:25 by NaN
Hi Nan,

My macro knowledge is indeed bad.

But the NoPar macro works. For example 10 optional parameters I don't want to use is coded NoPar(10) and the macro acording to your instruction is
NoPar macro Num:=<1>

LOCAL a1, a2
a1 equ <Num>
a2 = 0
while a1 ne a2
push 0
push DISP_E_PARAMNOTFOUND
push 0
push VT_ERROR
a2 = a2 + 1
endm
endm


Now if I want to put a value in such optional parameter as Open Book readonly. The readonly parameter should be TRUE. I call a macro like this: Par(VT_BOOL,boolVal,TRUE) and the macro is
Par macro _vt,_union,_value

LOCAL a,v
a equ _vt
v equ <_value>
push 0
push (v
push 0
push a)
endm

The red part is not used. This works with TRUE and FALSE but nothing else. Perhaps a number can work but I haven't tested. Text doesn't work. In fact I am rather suprised that it worked for boolean. I don't understand the parantheses before v and after a. The compiler told me to put them there. When this probleme is solved I intend to show an example how to use the tool.

Best regards
Posted on 2004-04-21 17:06:13 by minor28
Im confused as well what the parentheses is required for... And not 100% sure i follow what your problem is, but my suggestion would be to try this macro on for size
VAR MACRO v2:=<0>, v1:=<VT_I4>

if @InStr(1,v1,<VT_R8>) NE 0
push v1
push 0
push DWORD PTR [v2]
push DWORD PTR [v2+4]
else
push v1
push 0
push v2
push 0
endif
ENDM


Its some what robust in that it will handle DWORDS, PTRS, REAL8's, BOOLS, Etc.

Ex:

VAR ebx, VT_R8 ; ebx = addr of REAL8 value
VAR 3 ; Defult is VT_I4
VAR TRUE, VT_BOOL

Etc.

Like the last macro, I didnt test it, i only whipped it up on the fly for you. Lemme know if this helps you out.

PS: If you want inline macros out of these, simply do the following



$VAR MACRO v1:=<1>, v2:=<VT_I4>
VAR v1, v2
EXITM <> ;; Return nothing at all
ENDM


$NoPar MACRO a1:=<1>
NoPar a1
EXITM <> ;; Return nothing at all
endm


Enjoy!
:alright:
:NaN:
Posted on 2004-04-21 21:54:07 by NaN
Hi

The parantheses confusion was due to my way to call the macro. I wrote "Par(VT_BOOL,boolVal,TRUE)" with parantheses.

Now I have two macros working
NoPar macro Num:=<1>

LOCAL a1, a2
a1 equ <Num>
a2 = 0
while a1 ne a2
push 0
push DISP_E_PARAMNOTFOUND
push 0
push VT_ERROR
a2 = a2 + 1
endm
endm


with a call from "NoPar X" and
Par MACRO v1:=<VT_I4>,v2:=<0> 

if @InStr(1,v1,<VT_R8>) NE 0
push 0
push DWORD PTR [v2]
push 0
push v1
else
push 0
push v2
push 0
push v1
endif
ENDM


with a call from "Par VT_BOOL,TRUE". The last one works with bool, pointers etc. However sometimes the "Par VT_INT,eax" (eax==00000002) works and sometimes not. I can't understand why. These macros eliminate the need of the VARIANT structure.

Your inline proposal is interesting. I tried this macro but failed
Params macro args:VARARG


LOCAL arg
for arg,<&args>
if @InStr(1,arg,<$NoPar 3>) ne 0
$NoPar MACRO a1:=<1>
NoPar a1
EXITM <> ;; Return nothing at all
endm
else
$Par MACRO v1:=<1>, v2:=<VT_I4>
Par v1, v2
EXITM <> ;; Return nothing at all
ENDM
endif
endm
endm

called from "Param NoPar 3" and how do I do if a parameter is not a variant.

I attach the excel example and the COM.exe. I put in a simple VB browser. I don't know if it vill easy up the use of the tool.

I you don't quit excel with the button you have to terminate it with the tasm manager.
Posted on 2004-04-22 11:08:52 by minor28
I forgot to attach the excel example. There are no security arrangements in the code so if you puch buttons in wrong order the app will probobly crash. Then you have to terminate excel with the task manager
Posted on 2004-04-22 11:22:13 by minor28
Your well on your way with COM and Active-X automation.

As for the macro's, i think you got me misunderstood. I ment inline to be used in this sort of case


; Stack push order ->
$NoPar(2) $Par(VT_BOOL, TRUE)
call [ebx].ComMethod

Which would produce the following code:
00401C77  |. 6A 00          PUSH 0

00401C79 |. 68 04000280 PUSH 80020004
00401C7E |. 6A 00 PUSH 0
00401C80 |. 6A 0A PUSH 0A
00401C82 |. 6A 00 PUSH 0
00401C84 |. 68 04000280 PUSH 80020004
00401C89 |. 6A 00 PUSH 0
00401C8B |. 6A 0A PUSH 0A
00401C8D |. 6A 00 PUSH 0
00401C8F |. 6A 01 PUSH 1
00401C91 |. 6A 00 PUSH 0
00401C93 |. 6A 0B PUSH 0B
00401C95 |. E8 DCFFFFFF CALL [ebx+04]


I hope this is more clear to you.

Below is the macros i used to produce the code above
NoPar macro Num:=<1>

LOCAL a1, a2
a1 equ <Num>
a2 = 0
while a1 ne a2
push 0
push DISP_E_PARAMNOTFOUND
push 0
push VT_ERROR
a2 = a2 + 1
endm
endm

Par MACRO v1:=<VT_I4>,v2:=<0>
if @InStr(1,v1,<VT_R8> ) NE 0
push 0
push DWORD PTR [v2]
push 0
push v1
else
push 0
push v2
push 0
push v1
endif
ENDM

VT_ERROR equ 10
DISP_E_PARAMNOTFOUND equ 80020004h



$Par MACRO v1:=<VT_I4>,v2:=<0>
Par v1, v2
EXITM <> ;; Return nothing at all
ENDM


$NoPar macro Num:=<1>
NoPar Num
EXITM <> ;; Return nothing at all
endm


Regards,
:NaN:
Posted on 2004-04-22 18:43:44 by NaN
I have worked the COM tool over and it fullfills my needs now. I have added a VB browser more like the one shiped with VB6.0. I have also added possibility to launch the com help files from help menu or with F1. I believe it is easier to code asm if you can see the corresponding VB code and help.

I have only tested the tool on win2k and Excel. It will only work if you have TLBINF32.dll. This dll i shiped with VB6.0 and Visual studio. I don't know if it is legal to add it to the tool but you can google after it. Registration of the dll can be done with the tool.

The Access file holds the asm code and macros. You can edit the text as you like.

If this tool is interesting for use in general I would be glad if someone will test it and comment it.
Posted on 2004-04-26 14:37:28 by minor28
New update version 1.2.0.

- fixed a bug

- You can search constants

- in function listing a third column showing return pointers to function pointer. Clicking on the pointer opens the new function members, even if the function is in an external library.
Posted on 2004-04-28 15:53:17 by minor28
Hi Minor28,

Error when starting com.exe under windows 2000 sp3.

Regards
ipadilla
Posted on 2004-05-02 23:23:22 by ipadilla
Hi ipadilla,

I don't understand spanish. It looks like: error during startup. Can't find name of database and terminating the application or something.

Have you copied the Com.mdb to application folder. It is an access database with code snippets and macros.
Posted on 2004-05-03 13:28:28 by minor28