accessing component property from another app

I have written a non-visual component derived from TComponent, If placed in two different applications (not forms), how can I access a property in one app from the other app and vise versa? As well as within the same app?
It cannot use messages or Client/Server. I'm trying to keep it small.

NOTE: I'm using WIN95 and D3.
zolicAsked:
Who is Participating?
 
pjdbConnect With a Mentor Commented:
I've looked over your code. I receive the error in Unit2:

Published field 'data' not a class nor interface type

{Declaration of the component it self}
TMyComponent=Class(TComponent)
  data:PMyRecord;        <--------- ERROR
End;

My Email is nospam@pdq.net

I'll keep playing with it and if it works, I'll wait till tomorrow to grade you and give you 5 more points.

Thanks for the help. This one is over my head.

0
 
pjdbCommented:
Can you map some memory to allow the two applications to read/write the same block of memory? If so, just create the component at runtime in a map area. The first launch application will create the block and the second will obtain access to it.

JDB
0
 
zolicAuthor Commented:
That's my problem, If I map the memory, how does the component in the other app find it. Keep in mind, these are different apps, so how do I find the component and the mapped memory? Also, The last apps' component needs to free the memory as well even if it didn't create it.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
JimBob091197Commented:
Hi Zolic

Would CreateFileMapping work (along with MapViewOfFile)?  You call CreateFileMapping with a unique name and it creates a shared area of memory which can be accessed by 2/more apps.  Each app accesses the memory area through the unique name you use.

(You can look at http://www.experts-exchange.com/topics/comp/lang/delphi/Q.10050013 to see my comments on how to use CreateFileMapping and MapViewOfFile if you're unsure.)

JB
0
 
pjdbCommented:
Try the following :

type
  PMyComponent=^TMyComponent;
  TMyComponent=class(Tcomponent)
    {your stuff}
  end;

{.......}

procedure Tform1.FormCreate(Sender: TObject);

0
 
pjdbCommented:
What you proposed looked like it might have merit, but I tried every way possible and still could not get the unit to work. Besides each component needs its own property.
Perhaps more information would be of some help.
Here is what I am trying to do:

The component looks for a previous instance of itself from another app OR from the same app.
If not found, it creates itself. If found, it gives all of the other components the pointer of its FReceived property.

Any component can transmit data to any or all other components.

Using a thread, when a components' FReceived property is changed, an OnChange event kicks in.

Perhaps Mutexes or semaphores?

0
 
zolicAuthor Commented:
The points go up every day until I can get this up and running.

0
 
zolicAuthor Commented:
I've try the code, and after correcting some mistakes i've found that i can't share objects..... I've modify the solution in order to share the data and not the all component. Now you have a MyRecord which is the data from the component, MyComponent the component itself and MyMap the structure of the share memory. The code gets more complex, but it seems to work (I've test with 2 instance of the same program and they are able to share data).

If you prefer, give your Email, i will send you the test program

JDB

Unit Unit1;

Interface

Uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

Type
  TForm1 = class(TForm)
    Edit1: TEdit; {area to test the data sharing}
    Button1: TButton; {display to memory}
    Button2: TButton; {memory to display}
    procedure FormClose(Sender: TObject; Var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  Private
    { Private declarations }
  Public
    { Public declarations }
  End;

Var
  Form1: TForm1;

Implementation

Uses
      Unit2;

{$R *.DFM}

Var
  MyComponent:TMyComponent;

Procedure TForm1.FormShow(Sender: TObject);
{Display the form}
Begin
      MyComponent:=TMyComponent.Create(Application);                          {Create the component}
      DoFileMapBegin;                                                                                                                              {map the common memory}
  MyComponent.data:=@MyMap^.Data;                                         {Put the pointor on the shared memory in the component}
  form1.caption:='Instance #' + IntToStr(MyMap.instance); {Change the title of the form to know which intance it is (usefull only for debuging)}
End;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
{closing the form}
Begin
      MyComponent.data:=nil;      {Remove reference on the shared memory (Needed incase a component method start)}
      DoFileMapEnd;                                    {unmap the shared component}
  MyComponent.Free;       {Destroy the component}
End;

Procedure TForm1.Button1Click(Sender: TObject);
{get data from the Shared memory}
Begin
      Edit1.Text:=MyComponent.data^.Text;
End;

Procedure TForm1.Button2Click(Sender: TObject);
{put data to the shared memory}
Begin
      MyComponent.data^.Text:=Edit1.Text;
End;

End.      {Unit1}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Unit Unit2;

Interface

Uses
      Classes;

Type
      {Declaration of the data type of the component to be shared}
      PMyRecord=^TMyRecord;
      TMyRecord=record
        {put your stuff. I've put just a string to test it}
        text:ShortString;
  end;
  {Declaration of the component it self}
      TMyComponent=Class(TComponent)
            data:PMyRecord;
      End;
  {Declaration of the share memory type}
      PMyMap=^TMyMap;
      TMyMap=Record
            Instance:Byte;
            data:TMyRecord;
      End;

Procedure DoFileMapBegin;
procedure DoFileMapEnd;

Var
      MyMap:PMyMap;      {Pointor on the shared memory (you'd better use MyComponent.data^)}

implementation

Uses
      Forms, Windows;

var
  HMapping: THandle;

procedure DoFileMapBegin;
{map the common memory}
var
  llInit: Boolean;
  lInt: Integer;
begin
      {Map the memory}
      try
        HMapping:=CreateFileMapping($FFFFFFFF, nil, page_readwrite, 0, sizeof(TMyMap), pchar('hook memory share'));
        llInit:=(GetLastError()<>error_already_exists);
        if (hMapping=0) then
        begin
                  {Can''t Create Memory Map}
          Application.Terminate;
          exit;
        end;
        MyMap:=MapViewOfFile(HMapping, file_map_all_access, 0, 0, 0);
        if MyMap=nil then
        begin
                  {Can''t View Memory Map}
          CloseHandle(HMapping);
          Application.Terminate;
          exit;
        end;
      except
  end;
      Inc(MyMap^.Instance);      {Count the numbver of instances}
end;      {DoFileMapBegin}

procedure DoFileMapEnd;
{unmap the common memory}
begin
      Dec(MyMap^.Instance);      {Decount the instance}
  {Release memory}
  try
        if MyMap<>nil then
          UnMapViewOfFile(MyMap);
    if HMapping <> 0 then
          CloseHandle(HMapping);
  except
  end;
end;      {DoFileMapEnd}

End.      {Unit2}

0
 
zolicAuthor Commented:
I got the app to work, and its almost what I want.
It works with one common property. I beleive I can design personal properties around it though. The last part is that all other apps need to know when the property changes. AND protection from collisions.
I think I can do this. I'll grade you tomorrow. Thanks.

BTW What's you email?

0
 
zolicAuthor Commented:
My Email is JeanDitBailleulP@usa.net

I think that the way to synchronize the apps is to use the SendMessage function from API.

JDB

0
 
pjdbCommented:
Thank you pJDB, your answer will work out just fine. I gave you an A.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.