Link to home
Start Free TrialLog in
Avatar of felonius
felonius

asked on

I am creating an ActiveX: How do I pass records?

Hi,

I am in the process of making an ActiveX control in Delphi. I started out using the wizard and then added methods and some records in typelib on my own.

All works fine when I just pass an integer or other primitive types.

However, I have made some records in the typelib and I would like to pass either pointers to these or the records themselves in method calls:

E.g. I have a record:

  dxx_vector = packed record
    x: Single;
    y: Single;
    z: Single;
  end;

And I want to add this record to the ActiveX (is already done) and allow users of the ActiveX to access it (already works) and pass it as parameter (how?). And can this be done both as pass-by-value and pass-by-reference?

I tried adding a parameter of type "dxx_vector" but the resulting code just passes a TGUID. How do I use this to access the record or am I doing something complete wrong here?

Jacob Marner, B.Sc.
Avatar of TheNeil
TheNeil

Bit shaky on this subject but I think you need to pass it as an OLEVariant. It's been a while since I journeyed down this branch of Delphi and I remember anything else

The Neil =:)
Avatar of felonius

ASKER

Hmm,

I *can* get Delphi to show OLEVariant in the Delphi control implementation, if I in the typelib define it as VARIANT. However, the activeX client will then see it as a Variant which was not the intention. And even if I had to go with the variant solution I don't have the fainted idea on how to convert the OleVariant to my record.

Where do I find information about these kind of things. The Delphi on-line help is very brief on the subject of records in typelibs.

I would like to add that the first attempt I made by inserting a "dxx_vector" directly into the typelib specification seemed to work on activeX client side where it looked right. Unfortunately I just don't how in the Delphi implementation to handle the TGUID presented here.

A solution that can help me get on will be rewarded. If there is somebody that can help me out to get over this problem in a clean way I am even willy to raise the points to 500.

Jacob
ASKER CERTIFIED SOLUTION
Avatar of Epsylon
Epsylon

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I am using Delphi 5 Enterprise with Update pack 1 and I don't have this bug.

Here you can download the update(s):

http://www.borland.com/devsupport/delphi/downloads/index.html
Yes, updating Delphi certainly did the trick and the Delphi interface now is shown as the correct record type. How stupid of me not to have done that a long time ago...

No wonder, I couldn't get it to work.

Let me just check it out if it actually works.

Does any of you know whether it is possible to pass records both by value and by reference in an ActiveX. If so, how do I differentiate between them in typelib specification?

Jacob
Hmm, the ordeal does not seem over yet.

In the interface the signiture is like this: (autogenerated)

function  map_addinstance(const filename: WideString; origin: {??dxx_vector} OleVariant; angle: angle, locked: Integer): Integer; dispid 1;

And in the CoClass it is like this: (autogenerated)

    function map_addinstance(const filename: WideString; origin: dxx_vector; angle, locked: Integer): Integer; safecall;

These does not match. What is {??dxx_vector} and how do I get them to match?

Jacob
In the parameter list (Parameters tab in the TypeLibrary window) you can set the type to dxx_vector to pass it as value, or as dxx_vector* to pass is as reference.
Also check out the pulldown menu. Your record must be listed twice in there somewhere...
The top one is pasted wrong. Here the real is:

function  map_addinstance(const filename: WideString; origin: {??dxx_vector} OleVariant; angle,
locked: Integer): Integer; dispid 1;

Sorry.
What kind of ActiveX project is it? ActiveForm, Automation Object or ComObject?
I clicked "new" and then in the ActiveX property page I selected "ActiveX control" - and that started a wizard. (Delphi 5 with update 1 :-) ) Without knowing for sure I assume that is an automation object.

I just tried creating some more methods with record parameters in them and it keeps happening this difference in declarations.

(Epsylon: As promised - if you get me through this (almost there I think) I will award extra points)

Jacob
Hmm, I just tried making new project with the wizard and it is all different with the update 1 installed. I suspect that Borland has made a number of changes and that may be what causes my code above to fail.

So for now I will just stop here and come back again later and ask more questions if needed.

Thank you all for your help.

Jacob Marner
I'm not sure what you are trying to do but I think you started on the wrong track (I could be wrong).


For an automation object:

File menu > close all
File menu > new > ActiveX tab > ActiveX Library
File menu > new > ActiveX tab > Automation Object


For a COM object:

File menu > close all
File menu > new > ActiveX tab > ActiveX Library
File menu > new > ActiveX tab > COM Object
I need to do an actual Automation object (an OCX for use in visual basic). The old version I had of the same project was made the way I explained, but the code that wizards make now are different. So I think you are right - I redo the project architecture with the automation object wizard.

thanx.

(FYI: It is being used for a 3D engine. Check it out at www.eldermage.com)

Jacob
Oh.. well.. thanks for the points  :o)

OCX is used for graphical objects, like buttons, listviews etc, or even whole forms. An Automation or COM object is a DLL when 'in-process server', or an exe when 'out-of-process server'.
I am making a graphical object (a rendering window). Does this mean I should use another wizard?

Jacob
Hi Jacob, due to a bug in EE I don't receive email notifications anymore atfer you accpted my comment. This happens on all paqs :o(((

Do you still have problems?