Solved

Using IDataObject

Posted on 1998-04-23
13
421 Views
Last Modified: 2010-04-06
I want to use IDataObject to pass data across a COM interface.  How do I do this.  My COM server is an in-process activeX server with an interface decended from IDispatch using the type library editor.

BigMadDrongo
0
Comment
Question by:BigMadDrongo
  • 7
  • 6
13 Comments
 
LVL 4

Expert Comment

by:d003303
Comment Utility
Yo,
where do you want the data to go today ;-) The IDataObject interface is quite open, so you may have to supply a LOt of different data formats in that object. If you want to exchange data only between COM objects written by yourself you could declare your own format, but I think you will not use IDataObject then.
I guess you want to use IDataObject to communicate with the shell. Do you want to READ data from IDataObject or WRITE data through a IDataObject ?

Slash/d003303
0
 

Author Comment

by:BigMadDrongo
Comment Utility
What we have is two COM in-process servers which need to share a large amount of data.  This data is stored in a class derived from TComponent, which contains various standard data types and a collection.  Each item in the collection contains various standard data types as well as 3 other collections.  Because there are collections of collections, I can't stream the data into a memory stream and copy that memory stream across the interface  as a variant array because only the first level of collections is stored in the stream using the WriteComponent method.  IDataObject has been recomended to me as a means of sharing this data, but I have no idea how to use it.  I tried to comprehend Kraig Brockschmidt's Understanding Ole, but couldn't, having no knowledge of C++.  If you know hoe to use it, any help will be appreciated, or if you can suggest an alternative method, then I'm all ears.

Cheers

BigMadDrongo
0
 
LVL 4

Expert Comment

by:d003303
Comment Utility
OK,
it does not matter what interface you use. IDataObject is a standard interface to the OLE world. But very complex to use.
So your goal is to stream private data over a COM interface between private COM objects. So we should first focus on the data itself.
It will be best to use the internal streaming system of Delphi. Let's take a look at your object structure :

MyComponent
-MyProperty1
-MyProperty2
-MyCollection1
 -MyCollectionItem1.1
  -MyCollection2
   -MyCollectionItem2.1
   -MyCollectionItem2.2
 -MyCollectionItem1.2
  -MyCollection2
   -MyCollectionItem2.1
   -MyCollectionItem2.2
 -MyCollectionItem1.3
  -MyCollection2
   -MyCollectionItem2.1
   -MyCollectionItem2.2

Most important is that all collections get saved. That is the main thing, not the interface it is streamed over.
To get all your data saved, you will have to override the DefineProperties method of MyCollection1 that each collection item can stream its containing collections. You will need to design a read and write method for the first level of the collections. I'll take a look how to do this in detail.
Again, the interface is not important. If you can use a stream to get your data saved and read again, you've got it !

Slash/d003303
0
 

Author Comment

by:BigMadDrongo
Comment Utility
Where might I find the basic structure for the define properties method?  What code will I need to put in it when I override it.  Unfortunately I've taught myself Delphi from books and although I have overridden some simple functions, I wouldn't know where to start with overriding Define Properties.  Any guidance would be greatly appreciated!

BigMadDrongo
0
 
LVL 4

Expert Comment

by:d003303
Comment Utility
Yo,
the DefineProperties method defines how your component stores its data. The method

procedure MyComponent.DefineProperties(Filer: TFiler);
begin
  Filer.DefineBinaryProperty('AProperty', ReadAProperty, WriteAProperty, ShallWeWrite);
end;

would notify the Filer object that it should use the ReadAProperty and WriteAProperty to read/write the AProperty property in binary and checks with the ShallWeWrite method if the property shall be written or not. Check the online help on the DefineBinaryProperty and DefineProperty methods.
If you were using only components and not collections, everything would be saved automatically, because every component writes its contained components. So you must close this gap that your collection will write all collections of the containing collection items.
More clearer or more confused now ? I'll give a small example later on.

Slash/d003303
0
 

Author Comment

by:BigMadDrongo
Comment Utility
It's a bit clearer now.  I take it I need to define ReadAProperty and WriteAProperty as procedures which store components into a stream, and the components are of the type passed in as the 'AProperty' string.  How do I go about writing these procedures?  I've looked up TStreamProc in the help files and in the Delphi source, but with no luck.  If you have an example, it would be appreciated.

BigMadDrongo
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 4

Expert Comment

by:d003303
Comment Utility
OK, i'll prepare an example.

Slash/d003303
0
 

Author Comment

by:BigMadDrongo
Comment Utility
Slash/d003303

Thanks very much.  If it is easier, you can contact me by e-mail on

James_R_Bennett@SBPHRD.COM

Cheers

BigMadDrongo
0
 

Author Comment

by:BigMadDrongo
Comment Utility
I found some info in the Delphi Developers Handbook about the define properties method, and I think I have the hang of it.  What I do is the following:

procedure TRxnScheme.DefineProperties(Filer: TFiler);
begin
  Filer.DefineProperty('fNumberOfCompounds', ReadCompounds, WriteCompounds, True);
  Filer.DefineProperty('fNumberOfAssociations', ReadAssociations, WriteAssociations, True);
end;

procedure TRxnScheme.ReadCompounds(Reader: TReader);
begin
  fNumberOfCompounds := Reader.ReadInteger;
end;

procedure TRxnScheme.WriteCompounds(Writer: TWriter);
begin
  Writer.WriteInteger(fNumberOfCompounds);
end;

procedure TRxnScheme.ReadAssociations(Reader: TReader);
begin
  fNumberOfAssociations := Reader.ReadInteger;
end;

I can stream this into a file, and it stores the relevant bits.  One problem I do have is that some of my properties are variants and enumerated types, and there are no methods in TReader or TWriter to read and write these two types.  How do I read/write them?

Cheers

BigMadDrongo
0
 
LVL 4

Expert Comment

by:d003303
Comment Utility
Yo,
you will have to write an algorithm that covers the reading/writing process. So e.g. the first thing to save in a variant is the variant type, then depenging on the type its content. Reading is the same thing vice-versa. Enumerations can be saved/read as a set.

Slash/d003303
0
 

Author Comment

by:BigMadDrongo
Comment Utility
Slash/d003303

I've managed to get it all working, streaming to a file and back quite successfully.  If you want the points for your help, just post an answer, and they're yours!

Cheers for your help.

BigMadDrongo
0
 
LVL 4

Accepted Solution

by:
d003303 earned 200 total points
Comment Utility
Yo BigMadDrongo,
nice that it all works !

Slash/d003303
0
 

Author Comment

by:BigMadDrongo
Comment Utility
Cheers for all your help!

BigMadDrongo
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Firewall issues 6 84
IExtractImage Delphi 14 162
delphi exception 7 58
Delphi - replicating a form 8 57
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now