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
Thanks in advance
Peerapol
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
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.
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.
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('Sen dMessageTi mout Test Message');
end;
procedure TForm1.Button1Click(Sender : TObject);
var
MsgResult: DWORD;
begin
{send the message, and time out after 300 milliseconds}
SendMessageTimeout(HWND_TO PMOST, 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=UserMess age 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('Sen dMessageTi mout Test Message');
end;
end.
Regards Barry
ps.
if it easier to build i can just send the projects via email.
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('Sen
end;
procedure TForm1.Button1Click(Sender
var
MsgResult: DWORD;
begin
{send the message, and time out after 300 milliseconds}
SendMessageTimeout(HWND_TO
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=UserMess
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('Sen
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.
Tim.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
Tim.
Atari, huh, sorry, i'm newbie here :o)
No problem, roupik... (-:
No problem... =O)
Welcome to EE to you too!
Tim.
Welcome to EE to you too!
Tim.
you could also use the WM_COPYDATA message
GL
Mike
GL
Mike
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.
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)
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
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
The Neil