minor28
Code Warrior

Offline
Posts: 339
|
 |
« on: 2004-04-15 22:15:47 » |
|
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
|
|
|
|
|
Logged
|
Minor28
|
|
|
|
NaN
|
 |
« Reply #1 on: 2004-04-16 03:50:58 » |
|
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:
|
|
|
|
|
Logged
|
May fortune favor the foolish...
|
|
|
|
japheth
Guest
|
 |
« Reply #2 on: 2004-04-16 07:33:26 » |
|
Hi minor28,
the [lcid] attribute - for parameters - is described in MIDL language reference. it is always the last parameter, with the exception of a [retval] parameter.
Japheth
|
|
|
|
|
Logged
|
|
|
|
minor28
Code Warrior

Offline
Posts: 339
|
 |
« Reply #3 on: 2004-04-17 09:37:44 » |
|
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
|
|
|
|
|
Logged
|
Minor28
|
|
|
|
japheth
Guest
|
 |
« Reply #4 on: 2004-04-17 14:57:59 » |
|
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
|
|
|
|
|
Logged
|
|
|
|
minor28
Code Warrior

Offline
Posts: 339
|
 |
« Reply #5 on: 2004-04-19 15:58:44 » |
|
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
|
|
|
|
|
Logged
|
Minor28
|
|
|
|
NaN
|
 |
« Reply #6 on: 2004-04-19 22:12:35 » |
|
Interesting tool there... I hope you share it when your finished. :alright:
Regards, :NaN:
|
|
|
|
|
Logged
|
May fortune favor the foolish...
|
|
|
minor28
Code Warrior

Offline
Posts: 339
|
 |
« Reply #7 on: 2004-04-20 15:04:09 » |
|
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
|
|
|
|
|
Logged
|
Minor28
|
|
|
|
NaN
|
 |
« Reply #8 on: 2004-04-20 16:32:34 » |
|
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:
|
|
|
|
|
Logged
|
May fortune favor the foolish...
|
|
|
minor28
Code Warrior

Offline
Posts: 339
|
 |
« Reply #9 on: 2004-04-20 18:36:38 » |
|
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
|
|
|
|
|
Logged
|
Minor28
|
|
|
|
NaN
|
 |
« Reply #10 on: 2004-04-21 04:48:25 » |
|
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:
|
|
|
|
|
Logged
|
May fortune favor the foolish...
|
|
|
minor28
Code Warrior

Offline
Posts: 339
|
 |
« Reply #11 on: 2004-04-21 22:06:13 » |
|
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
|
|
|
|
|
Logged
|
Minor28
|
|
|
|
NaN
|
 |
« Reply #12 on: 2004-04-22 02:54:07 » |
|
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:
|
|
|
|
|
Logged
|
May fortune favor the foolish...
|
|
|
minor28
Code Warrior

Offline
Posts: 339
|
 |
« Reply #13 on: 2004-04-22 16:08:52 » |
|
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.
|
|
|
|
|
Logged
|
Minor28
|
|
|
minor28
Code Warrior

Offline
Posts: 339
|
 |
« Reply #14 on: 2004-04-22 16:22:13 » |
|
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
|
|
|
|
|
Logged
|
Minor28
|
|
|
|