Solved

accessing component property from another app

Posted on 1998-04-28
11
170 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
  • 5
  • 5
11 Comments
 
LVL 1

Expert Comment

by:pjdb
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 1

Expert Comment

by:pjdb
Comment Utility
Try the following :

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

{.......}

procedure Tform1.FormCreate(Sender: TObject);

0
 
LVL 1

Expert Comment

by:pjdb
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

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

0
 

Author Comment

by:zolic
Comment Utility
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 210 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Thank you pJDB, your answer will work out just fine. I gave you an A.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

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

10 Experts available now in Live!

Get 1:1 Help Now