我正在用C ++编写一个应用程序,它将向Delphi编写的应用程序发送一条消息。
这是我的接收器应用程序:
单击按钮后,Edit1.Text
将作为命令行参数通过ShellExecute()
发送到发件人应用程序(C ++)。
发送方应用会将参数作为WM_COPYDATA
消息发送回接收方应用,然后将其显示在Edit2
文本框中。
这是Delphi应用程序的代码(Delphi 10.3 Rio):
procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(0, 'open', 'deneme.exe', PWideChar(Edit1.Text), nil, SW_HIDE);
end;
procedure TForm1.MesajAl(var Mesaj: TMessage);
var
Veri: PCopyDataStruct;
begin
Veri := Pointer(Mesaj.LParam);
Edit2.Text := PChar(Veri^.lpData);
end;
这是我的C ++应用程序的代码(代码:: Blocks IDE):
#include <iostream>
#include <windows.h>
#include <tchar.h>
using namespace std;
int main(int argc, char* argv[])
{
if (argc < 2)
{
return 0;
}
else
{
HWND hwnd = FindWindow(NULL, "Form1");
string alinanMesaj;
LPCTSTR gonderilecekMesaj = alinanMesaj.c_str();
COPYDATASTRUCT cds;
cds.cbData = sizeof(TCHAR)*(_tcslen(gonderilecekMesaj) + 1);
cds.dwData = 1;
cds.lpData = (PVOID)gonderilecekMesaj;
SendMessage(hwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)(LPVOID)&cds);
return 0;
}
}
问题是Edit2
文本框什么也没显示。
顺便说一下,我已经在这个网站上对WM_COPYDATA
进行了研究。但是尽管有这种情况,我还是无法自己解决问题。
那么,我该怎么办才能解决我的问题?
答案 0 :(得分:0)
我看到此代码的三个问题:
发件人正在发送空白数据,因为没有为alinanMesaj
分配任何值。
两个应用之间存在ANSI / UNICODE不匹配的情况。 Delphi代码使用Unicode字符串,而C ++代码使用ANSI字符串。 WM_COPYDATA
对字节进行操作,而不对字符进行操作。您必须为字符串数据选择一个字节编码,并且在两侧都与之保持一致。
VCL在内部使用WM_COPYDATA
,因此发送方需要将cds.dwData
字段设置为唯一值,例如RegisterWindowMessage()
,接收方必须在此之前进行验证解释cds.lpData
数据。
在说的话,请尝试以下方法:
var
MY_CDS_ID: UINT;
procedure TForm1.FormCreate(Sender: TObject);
begin
MY_CDS_ID := RegisterWindowMessage('MYCDSID'); // use whatever unique name you want
if MY_CDS_ID = 0 then
RaiseLastOSError;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// you really should be using CreateProcess() instead...
ShellExecute(0, nil, 'deneme.exe', PChar(AnsiQuotedStr(Edit1.Text, '"')), nil, SW_HIDE);
end;
procedure TForm1.MesajAl(var Mesaj: TMessage);
var
Veri: PCopyDataStruct;
s: UnicodeString;
begin
Veri := Pointer(Mesaj.LParam);
if Veri^.dwData = MY_CDS_ID then
begin
SetString(s, PWideChar(Veri^.lpData), Veri^.cbData div SizeOf(WideChar));
Edit2.Text := s;
end else
inherited;
end;
#include <iostream>
#include <windows.h>
#include <string>
int main(int argc, char* argv[])
{
if (argc < 2)
return 0;
HWND hwnd = FindWindow("TForm1", "Form1");
if (!hwnd)
return 0;
UINT MY_CDS_ID = RegisterWindowMessage("MYCDSID"); // must match the named used by the Delphi code
if (!MY_CDS_ID)
return 0;
std::wstring alinanMesaj;
int arglen = lstrlenA(argv[1]);
int wlen = MultiByteToWideChar(CP_ACP, 0, argv[1], arglen, NULL, 0);
if (wlen > 0)
{
alinanMesaj.resize(wlen);
MultiByteToWideChar(CP_ACP, 0, argv[1], arglen, &alinanMesaj[0], wlen);
}
COPYDATASTRUCT cds;
cds.cbData = sizeof(wchar_t) * alinanMesaj.size();
cds.dwData = MY_CDS_ID;
cds.lpData = const_cast<wchar_t*>(alinanMesaj.c_str());
SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(hwnd), reinterpret_cast<LPARAM>(&cds));
return 0;
}