问题
I have been searching to send a message from Microsoft Visual C++ to another application created in Delphi for 2 hours.
In delphi I know how to read the data. But I don't know exactly how to send a message in MVC++
I hope you can get me a code.
So for the next code I want a translation in Microsoft Visual Studio C++ 2010, my project it is a console project.
const
MY_MESSAGE = WM_USER + 4242;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
txt: string;
begin
txt := 'Hello World';
SendMessage(Form1.Handle, MY_MESSAGE, 0, DWORD(PChar(txt)));
end;
end.
And with this code I should read the data. Also I want to be compatible.
const
MY_MESSAGE = WM_USER + 4242;
type
TForm1 = class(TForm)
// Handler that receive the Message
procedure MessageReceiver(var msg: TMessage); message MY_MESSAGE;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.MessageReceiver(var msg: TMessage);
var
txt: PChar;
begin
txt := PChar(msg.lParam);
msg.Result := 1;
ShowMessage(txt);
end;
end.
So my application contains two parts: One in Microsoft Visual Studio, i use opencv and i want to send a message to the second application, which is created in Delphi.
回答1:
I don't know how to use the pipeline, but I have used before the following scheme:
Use WM_COPYDATA
message using SendMessage()
. Here is a reference
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649011(v=vs.85).aspx
and the example
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649009(v=vs.85).aspx
You will need to use FindWindow
to get a handle to the application you want to send the message to.
回答2:
You can use the WM_GETTEXT
or WM_COPYDATA
message to send buffers of data back and forth between applications. I once searched for a way to send a buffer like WM_GETTEXT
does, only with a different message. The original code can be found here:
http://www.nldelphi.com/forum/showthread.php?p=275167#post275167
I don't know if everything still works (haven't used it since), but it did back then.
// The order (first Buffer, then BufferLength) seems more sensible, although with
// WM_SETTEXT they are actually the other way around.
function SendTextMessage(Handle: THandle; Msg: Integer; Buffer: Pointer; BufferLength: Integer): Cardinal;
var
ProcessHandle: THandle;
ProcessId: Cardinal;
VirtualBuffer: Pointer;
begin
// Get the id of process to which the handle belongs.
GetWindowThreadProcessID(Handle, @ProcessId);
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
if ProcessHandle = 0 then
RaiseLastWin32Error;
// Allocate a virtual buffer in the process
VirtualBuffer := VirtualAllocEx(ProcessHandle, nil, BufferLength,
MEM_COMMIT, PAGE_READWRITE);
if VirtualBuffer = nil then
RaiseLastWin32Error;
try
// Send a message to the handle, passing the virtual pointer as a buffer
Result := SendMessage(Handle, Msg, BufferLength, Integer(VirtualBuffer));
// Read the resulting value from the virtual buffer into the given buffer
if not ReadProcessMemory(ProcessHandle, VirtualBuffer, Buffer, Result, Result) then
RaiseLastWin32Error;
finally
VirtualFreeEx(ProcessHandle, VirtualBuffer, BufferLength, MEM_RELEASE);
end;
end;
And call it like this:
var
h: THandle;
b: array[0..1024] of Char;
begin
h := Cardinal(StrToInt(Edit1.Text));
// Not like this
//SendMessage(h, WM_GETTEXT, 1024, Integer(@b));
// But like this
SendTextMessage(h, WM_USER+1, @b, 1024 * SizeOf(Char));
ShowMessage(b);
Read the message like this:
procedure WM_USERPLUS1(var Msg: TWMGetText); message WM_USER+1;
procedure TForm2.WM_USERPLUS1(var Msg: TWMGetText);
begin
with Msg do
Result := StrLen(StrLCopy(PChar(Text), PChar('Hallo wereld'), TextMax - 1)) * SizeOf(Char);
end;
It's probably just as easy to use WM_COPYDATA
, though. :D
来源:https://stackoverflow.com/questions/10126342/vc-sending-message-between-two-application