【问题标题】:VC++ sending message between two applicationVC++在两个应用程序之间发送消息
【发布时间】:2012-04-12 15:05:33
【问题描述】:

我一直在寻找从 Microsoft Visual C++ 向另一个在 Delphi 中创建的应用程序发送消息 2 小时。

在 delphi 中,我知道如何读取数据。但我不知道如何在 MVC++ 中发送消息

希望你能给我一个代码。

所以对于下一个代码,我想在 Microsoft Visual Studio C++ 2010 中进行翻译,我的项目是控制台项目。

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. 

我应该使用这段代码读取数据。我也想兼容。

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. 

所以我的应用程序包含两个部分:一个在 Microsoft Visual Studio 中,我使用 opencv,我想向第二个应用程序发送消息,它是在 Delphi 中创建的。

【问题讨论】:

  • 您的意思是使用 SendMessage 发送消息?
  • 我不确定,但我认为是其中之一。既然您知道如何在 Delphi 中阅读,您可以发布该代码,所以有人知道您需要什么样的写对应物?此外,由于您需要 VC++ 代码,因此这实际上不是 Delphi 问题。
  • 没有 Windows 管道这样的东西。你是说命名管道吗?
  • 你说得对,我刚刚重写了我的问题。
  • 您不能使用用户定义的消息来跨进程发送指针。您需要使用WM_COPYDATA

标签: delphi post message


【解决方案1】:

我不知道如何使用管道,但我之前使用过以下方案:

使用WM_COPYDATA 消息使用SendMessage()。这是一个参考

http://msdn.microsoft.com/en-us/library/windows/desktop/ms649011(v=vs.85).aspx

还有例子

http://msdn.microsoft.com/en-us/library/windows/desktop/ms649009(v=vs.85).aspx

您需要使用FindWindow 来获取您要向其发送消息的应用程序的句柄。

【讨论】:

  • 我不知道如何使用该代码。我不是 MVC++ 的程序员谢谢,我重写了我的问题,以便于理解
【解决方案2】:

您可以使用WM_GETTEXTWM_COPYDATA 消息在应用程序之间来回发送数据缓冲区。我曾经寻找一种方法来发送像WM_GETTEXT 这样的缓冲区,只是使用不同的消息。原始代码可以在这里找到:

http://www.nldelphi.com/forum/showthread.php?p=275167#post275167

我不知道一切是否仍然有效(从那以后就没有使用过),但当时确实如此。

// 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;

然后这样称呼它:

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);

像这样阅读消息:

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;

不过,WM_COPYDATA 可能同样易于使用。 :D

【讨论】:

  • 谢谢,我重写了我的问题,以便于理解
  • 你到底为什么要这样做而不是像大自然一样使用WM_COPYDATA?!
  • 就像我说的那样,使用 WM_COPYDATA 可能同样容易,但另一方面,它是一个有趣的练习,它允许您使用任何您想要的消息。随意不要使用它。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
相关资源
最近更新 更多