Page 1 of 1

How do you get the active object?

Posted: 9 Jun 2016 7:02
by Peter Muraya
Thomas,
In VB I used the following statement to obtain the active Excel application object

Code: Select all

... Set excel = GetObject(, "Excel.Application") ...
How would I use the comCreation:: libray to achieve the same result in Visual Prolog?

Posted: 9 Jun 2016 22:41
by Thomas Linder Puls
It seems that this code has more or less the same effect:

Code: Select all

class predicates     getActiveObject : (comDomains::nativeClassId CLSID, pointer MustBeNull, iUnknown IUnknown [out]) -> hResult HResult language apicall.   clauses     run() :-         CLSID = memory::alloc_atomic(),         R1 = com_native::cLSIDFromProgID("Excel.Application", CLSID),         R2 = getActiveObject(CLSID, null, Native),         Disp = comDispInterface::new(uncheckedConvert(iDispatch, Native), comMemory::release),         writef("%\n%\n%\n%\n", R1, R2, Native, Disp).
You should do proper error checking, especially on R2.

However the resulting "Disp" object is not as easy to use as in VB.

Posted: 10 Jun 2016 10:09
by Peter Muraya
Thank you Thomas. I will study your code more closely; yes, it's the kind of thing I was looking for.

Posted: 11 Jun 2016 5:45
by Peter Muraya
Thomas,
Now I understand what you meant when you said:-
However the resulting "Disp" object is not as easy to use as in VB.
Here is what I want to do in VB

Code: Select all

... set disp = getobject(,"Excel.applicaion") 'To display the name of the application, using the name property msgbox disp.name ....  
Here is how I tried to use the disp object

Code: Select all

... CLSID = memory::alloc_atomic(), com_native::cLSIDFromProgID("Excel.Application", CLSID)==0, getActiveObject(CLSID, null, Native)==0, Disp = comDispInterface::new(uncheckedConvert(iDispatch, Native), comMemory::release), Disp:getProperty("Name")==comdomains::string(Name), %<---------- I get n exception on this line vpiCommonDialogs::note(Name). ...
I get an exception on the indicated line, to the effect that the getDispId fails o the "name" property.
I'm stuck.

Posted: 13 Jun 2016 10:26
by Thomas Linder Puls
Well, it seemed that there was one more step in obtaining the "Active Excel Object", i.e. you have to query for the iDispatch interface:

Code: Select all

class predicates     getActiveObject : (comDomains::nativeClassId CLSID, pointer MustBeNull, iUnknown IUnknown [out]) -> hResult HResult language apicall.   clauses     run() :-         CLSID = memory::alloc_atomic(),         comExceptionCheck::check2(com_native::cLSIDFromProgID("Excel.Application", CLSID)),         comExceptionCheck::check2(getActiveObject(CLSID, null, IUnk)),         if memory::isNull(IUnk) then             write("No active Excel application\n")         else             Unk = comInterface::new(IUnk, comMemory::release),             IDisp = uncheckedConvert(iDispatch, Unk:queryInterface(iDispatch::iid)),             Disp = comDispInterface::new(IDisp, comMemory::release),             comDomains::string(Name) == Disp:getProperty("Name"),             stdio::write(Name)         end if.

Posted: 14 Jun 2016 7:43
by Peter Muraya
Thanks Thomas. Now it works fine.
Just curious.... how much memory is allocated by the statement

Code: Select all

CLSID = memory::alloc_atomic() ?
The Prolog documentation refers to #Count but this is applicable to

Code: Select all

memory::alloc_array(positive Count)

Posted: 15 Jun 2016 8:00
by Thomas Linder Puls
alloc_atomic allocates an element of the right type and with the right amount of memory. It does so by examining the type that it must return. A nativeClassId is a GUID which is 16 bytes (128 bits), so this invocation will 16 bytes.

alloc_array will allocate a piece of memory to hold an array containing Count values of the type in question. I.e. Count is not a memory size, but a count of elements.

These predicates works for structs (functors domains with a single functor) but not for functors domains with several alternatives, because such alternatives may have different size. Likewise they cannot allocate memory for a string, because it cannot guess how large a string you want.

In older code you may see:

Code: Select all

CLSID = uncheckedConvert(comDomains::nativeClassId, memory::allocAllocateAtomic(sizeOfDomain(comDomains::nativeClassId))),
So this "magic" is a lot easier to write.

alloc_array would correspond to code like this

Code: Select all

CLSIDArray = uncheckedConvert(comDomains::nativeClassId,     memory::allocAllocateAtomic(Count * sizeOfDomain(comDomains::nativeClassId))),

Posted: 15 Jun 2016 9:14
by Peter Muraya
This is very very clear now. Thanks.

Posted: 12 Oct 2016 16:04
by Tonton Luc
Hi,

I try to reproduce your code in VP7.3 => by what do I replace check2 ?

Code: Select all

clauses     onFileNew(_Source, _MenuTag):-         CLSID = memory::allocAtomicHeap(sizeOfDomain(comDomains::nativeClassId)),         comExceptionCheck::check2(com_native::cLSIDFromProgID("Excel.Application", CLSID)),         comExceptionCheck::check2(getActiveObject(CLSID, null, IUnk)),         if memory::isNull(IUnk) then             stdio::write("No active Excel application\n")         else             Unk = comInterface::new(IUnk, comMemory::release),             IDisp = uncheckedConvert(iDispatch, Unk:queryInterface(iDispatch::iid)),             Disp = comDispInterface::new(IDisp, comMemory::release),             comDomains::string(Name) == Disp:getProperty("Name"),             stdio::write(Name)         end if                 .

Posted: 16 Oct 2016 18:43
by Thomas Linder Puls
There is a check predicate that was used back then.