Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 861
  • Last Modified:

Delphi - How send a structure to an other probramm by using SendMessage function

HI everybody,

I'm tryind to send a structure from Program "A" to program "B" by using sendmessage function.

My structure is defined into a (Program "A" and Program "B") common library like this
==>

TIdentifier record of
  ID  : String;
  SID : String;
end;


Into program "A" I'm  fulling my structure as below
==>

Program "A"
var
   Identifier: TIdentifier;
begin
  Identifier.PID := 'PID';
  Identifier.SID := 'SID';
  sendmessage(ProgramBHandle,1101,0,integer(@Identifier));
end;


I'm receiving the message into program "A" like below
==>
procedure Tform1.WndProc(var Msg : TMessage);
var
  PID:string;
  MsgParm: integer;
  Identifier: TIdentifier;
begin
  if msg.Msg = 1101 then begin
    messagebeep(0);
    id := Pointer(msg.lParam);
    Identifier(id).
    PID:=id^.PID;
    showmessage(PID);
    PID:=id.PID;
    showmessage(PID);
  end;
  inherited;
end;

But my problem is... can't read my structure. I'm receiving the structure address but I can't
do anything.
0
jlvill
Asked:
jlvill
2 Solutions
 
philipjcCommented:
You may be getting an address but its not correct, remember in win32 each process has it own address space so when you try to read program A's address in program B, program B is actually looking in it own address space

To do what you want you should use memory mapped files or use some sort of interprocess communication like pipes etc.
0
 
aikimarkCommented:
TIdentifier record of
  ID  : String;


Identifier.PID := 'PID';
====================
How can this work?
0
 
aikimarkCommented:
philipjc is probably on the correct path.  You need to pass your object, not a pointer to your object.

Possible solution paths:
* memory mapped files (philipjc)
* named pipes (philipjc)
* atoms
* TCP (you can stream objects)
* UDP one-way messages (you need to establish msg structure)
* MSMQ for guraranteed delivery
* You can use the file system to transmit data (requires programs to hook the Windows Shell for changes notification or timer-based monitoring)
0
Independent Software Vendors: 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!

 
geobulCommented:
Hi,

The following is an example of using  WM_COPYDATA message:
The sending app:
----------
type
  TIdentifier = record
    PID  : String[255]; // it cannot be 'string' here
    SID : String[255];
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure SendToServer(WindowName: string; data: TIdentifier);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Identifier: TIdentifier;

implementation

{$R *.DFM}

procedure TForm1.SendToServer(WindowName: string; data: TIdentifier);
var
  COPYDATA: TCopyDataStruct;
  h: HWND;
begin
  h := FindWIndow(nil, PChar(WindowName));
  if IsWindow(h) then begin
    // Fill the COPYDATASTRUCT:
    with COPYDATA do begin
      dwData:= 0;
      cbData:= SizeOf(data); // size
      lpData:=@data; // address
    end;
    // Send to the server:
    SendMessage(h, // Who are we sending to?
             WM_COPYDATA,  // This message enables it all
             Handle,       // Handle of the sender
             Integer(@COPYDATA) // Address of the filled COPYDATASTRUCT
            );
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Identifier.PID := 'PID';
  Identifier.SID := 'SID';
  SendToServer('ServerApp', Identifier); // replace 'ServerApp' with the correct title or
          // modify SendToServer function to accept HWND directly.
end;
--------
The receiving app:
----------
type
  TIdentifier = record
    PID  : String[255];
    SID : String[255];
  end;

  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  data: TIdentifier;

implementation

{$R *.DFM}

procedure TForm1.WMCopyData(var Msg: TWMCopyData);
begin
  data := TIdentifier(Msg.CopyDataStruct^.lpData^);
  ShowMessage(data.PID+' '+data.SID);
end;
--------

Regards, Geo
0
 
esoftbgCommented:
download an example from:
page:        http://geocities.com/esoftbg/
  link:        Q_21057608.zip
0
 
jlvillAuthor Commented:
Great!!!
Thanks esoftbg
Thanks Geo P.S I corrected  FindWIndow(nil, PChar(WindowName)) by  FindWIndow(PChar(WindowName),nil)

It's working!

philipjc and aikimark you're right, the program not run in the same address space.

Thanks all of you ;-)
0

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now