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
LVL 25
Mr_PeerapolAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

TheNeilCommented:
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
0
GoodTimesCommented:
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
0
bryan7Commented:
listenning
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

MadshiCommented:
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.
0
AttarSoftwareCommented:
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.
0
intheCommented:
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.
0
AttarSoftwareCommented:
PS:  Welcome to Experts-Exchange, Peerapol ;O)

Tim.
0
roupikCommented:
This procedure sends 'A' in to notepad window - is it useful ?

procedure TForm1.Button1Click(Sender: TObject);      
var g,d:integer;
begin
   g:=findwindow('Notepad',nil);
     {Above finds the main window of the Application}
   d:=Childwindowfrompoint(g,point(50,50));
     {Above finds the window of the application's text box}
   sendmessage(d,wm_char,ord('A'),0);
     {Now send it a character!!}
end;    


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
AttarSoftwareCommented:
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.
0
roupikCommented:
Atari, huh, sorry, i'm newbie here :o)
0
MadshiCommented:
No problem, roupik...   (-:
0
AttarSoftwareCommented:
No problem... =O)

Welcome to EE to you too!

Tim.
0
edeyCommented:
you could also use the WM_COPYDATA message


GL
Mike
0
Mr_PeerapolAuthor Commented:
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.



0
roupikCommented:
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)
0
edeyCommented:
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
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.