Link to home
Start Free TrialLog in
Avatar of Mr_Peerapol
Mr_Peerapol

asked on

How to send a string to another program?

I want to send some string such as "Hello" to another program which I write. How can I  easily do?

Thanks in advance
Peerapol
Avatar of TheNeil
TheNeil

You could use the Windows clipboard (nasty) or use the Windows message system to allow the two programs to communicate (better). Program A will need to know the handle for Program B and can then send it a message. For security reasons it's better to actually get Program A to send a message indicating that it is about to send a message and then wait for Program B to send a message back indicating that it's ready. Program A then sends the string itself and you can add a further message from B to A to indicate that it has actually received it.

The Neil
Mr Peerapol:
There is quite an easy way of doing so:
what you should do is define a windows WM message. It should be of value WM_USER + XXX e.g  WM_USER + 100. The sending program should find the handle of your receiving program and use PostMessage to send it the string (using the message you defined). The receiving program should have a message handling routine which will receive the string.

e.g -
const
   WM_CUSTOM = WM_USER + 100;
type
TForm1 = Class(TForm);
.....
.....
Private
   procedure HandleMessage(Var Msg : TMessage); message WM_CUSTOM;

this procedure can process further handling of the string;

Any more explanations needed?

Cheers,

Omri
listenning
Or use memory mapped files (CreateFileMapping(dword(-1), ...) + MapViewOfFile) and named events (CreateEvent, SetEvent, WaitForSingleObject). Then you don't have the problem that one program needs to know the handle of the other one.
Using my suggestion is perhaps cleaner, but probably a bit more difficult...   :-)

Regards, Madshi.
Or, your programs can load each other like DLLs with the LoadLibrary API call, and then you can call a function in the other EXE directly :O)

EG:

---------------------------------------

{in program 1}
procedure ShowMyMessage( str : shortString ) ; stdcall ;
begin
  ShowMessage( str ) ;
end ;

exports
  ShowMyMessage ;

---------------------------------------
{and in program 2}
type
  tMsgProc = procedure( shortString ) ; stdcall ;

procedure DoIt ;
var
  h : longint ;
  p : pointer ;
begin
  h := LoadLibrary( 'C:\Program1.exe' ) ;
  if( h = 0 ) then exit ;
  p := GetProcAddress( h, 'ShowMyMessage' ) ;
  if( p = nil ) then exit ;
  tMsgProc( p )( 'Hello World' ) ;
  CloseHandle( h ) ;
end ;
----------------------------------------

Woohoo, piece of cake anyone?

Tim.
hello here a demo of a sender and a listener using the registerwindowsmessage() function:

unit SendMsgTimeoutSendU;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

{Whoops! This function is imported in the Delphi source code incorrectly; the
 return value should be BOOL, not LRESULT}
function SendMessageTimeout(hWnd: HWND; Msg: UINT; wParam: WPARAM;
  lParam: LPARAM; fuFlags, uTimeout: UINT; var lpdwResult: DWORD):BOOL; stdcall;

var
  Form1: TForm1;
  UserMessage: UINT;  // holds our user defined message identifier

implementation

{$R *.DFM}

{re-link the external function}
function SendMessageTimeout; external user32 name 'SendMessageTimeoutA';

procedure TForm1.FormCreate(Sender: TObject);
begin
  {register the user defined Windows messsage}
  UserMessage := RegisterWindowMessage('SendMessageTimout Test Message');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MsgResult: DWORD;
begin
  {send the message, and time out after 300 milliseconds}
  SendMessageTimeout(HWND_TOPMOST, UserMessage, 0, 0,
                     SMTO_NORMAL, 300, MsgResult);

  {indicate that the SendMessageTimeout function has returned}
  ShowMessage('Returned');
end;

end.


unit SendMstTimeoutGetU;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    ProgressBar1: TProgressBar;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure DefaultHandler(var Msg); override;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  UserMessage: UINT;  // holds our user defined message identifier

implementation

{$R *.DFM}

procedure TForm1.DefaultHandler(var Msg);
var
  iLoop: Integer;  // general loop counter
begin
  {process message normally}
  inherited DefaultHandler(Msg);

  {if this is our user defined message...}
  if TMessage(Msg).Msg=UserMessage then
  begin
    {...display some user interface objects}
    ProgressBar1.Visible := TRUE;
    Label2.Visible := TRUE;
    Form1.Repaint;

    {animate the progress bar for a short time}
    for iLoop := 0 to 100 do
    begin
      ProgressBar1.Position := iLoop;
      Sleep(10);
    end;

    {turn off the user interface objects}
    ProgressBar1.Visible := FALSE;
    Label2.Visible := FALSE;

    {indicate that the message was handled}
    TMessage(Msg).Result := 1;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  {register the user defined Windows message}
  UserMessage := RegisterWindowMessage('SendMessageTimout Test Message');
end;

end.


Regards Barry
ps.
if it easier to build i can just send the projects via email.
PS:  Welcome to Experts-Exchange, Peerapol ;O)

Tim.
ASKER CERTIFIED SOLUTION
Avatar of roupik
roupik

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
A comment would have been better roupik, then Peerapol can evaluate all of the ideas, see which works for him, and and allocate the points accordingly...

Tim.
Atari, huh, sorry, i'm newbie here :o)
No problem, roupik...   (-:
No problem... =O)

Welcome to EE to you too!

Tim.
you could also use the WM_COPYDATA message


GL
Mike
Avatar of Mr_Peerapol

ASKER

First of all, I would like to thank all of you to comment and propose your ideas for me.

For roupik, in fact your idea still cannot make me reach what I want. Because when I want to send a string message such as "Hello", I will have to send 5 times (1 character / time) , right? Anyway it still is okay for do like that.

For Madshi, your way is looked so good for my problem, but a little bit hard for me now. However, thank you very much.



yeah, repeat it 5 times for HELLO ;o)

or

I see some WM_COPYDATA was anounced here - try to find more about parameters - I think it's for bigger couple for data :o)
WM_COPYDATA passes a pointer to this structure:

typedef struct tagCOPYDATASTRUCT {  // cds

    DWORD dwData;
    DWORD cbData;
    PVOID lpData;
} COPYDATASTRUCT;


the lpdata member being a pointer to pretty much anything you want.



GL
Mike