Discussions related to Visual Prolog
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

How do you get the active object?

Unread post 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?
Mutall Data Management Technical Support
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post 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.
Regards Thomas Linder Puls
PDC
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post by Peter Muraya »

Thank you Thomas. I will study your code more closely; yes, it's the kind of thing I was looking for.
Mutall Data Management Technical Support
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post 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.
Mutall Data Management Technical Support
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post 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.
Regards Thomas Linder Puls
PDC
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post 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)
Mutall Data Management Technical Support
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post 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))),
Regards Thomas Linder Puls
PDC
Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29

Unread post by Peter Muraya »

This is very very clear now. Thanks.
Mutall Data Management Technical Support
User avatar
Tonton Luc
VIP Member
Posts: 204
Joined: 16 Oct 2001 23:01

Unread post 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                 .
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

There is a check predicate that was used back then.
Regards Thomas Linder Puls
PDC
Post Reply