?
Solved

accessing component property from another app

Posted on 1998-04-28
11
Medium Priority
?
190 Views
Last Modified: 2010-04-06
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.
0
Comment
Question by:zolic
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
11 Comments
 
LVL 1

Expert Comment

by:pjdb
ID: 1338702
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
 

Author Comment

by:zolic
ID: 1338703
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
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1338704
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 1

Expert Comment

by:pjdb
ID: 1338705
Try the following :

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

{.......}

procedure Tform1.FormCreate(Sender: TObject);

0
 
LVL 1

Expert Comment

by:pjdb
ID: 1338706
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
 

Author Comment

by:zolic
ID: 1338707
The points go up every day until I can get this up and running.

0
 

Author Comment

by:zolic
ID: 1338708
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
 
LVL 1

Accepted Solution

by:
pjdb earned 840 total points
ID: 1338709
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
 

Author Comment

by:zolic
ID: 1338710
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
 

Author Comment

by:zolic
ID: 1338711
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
 
LVL 1

Expert Comment

by:pjdb
ID: 1338712
Thank you pJDB, your answer will work out just fine. I gave you an A.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses
Course of the Month9 days, 3 hours left to enroll

764 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