以前很少用过不同程序间的消息机制,今天才知道sendmessage这样的api在不同程序间传递消息时,无法通过Lparam传递附加字符串或其它信息。这个应该是不同程序之间地址空间不一致,导致传指针过去也取不到正确的值。
这次变通的方法:先定义好自己的消息,然后给目标程序发送WM_COPYDATA消息,将自定消息的编号赋给COPYDATASTRUCT的dwData,将附加字符串信息赋给COPYDATASTRUCT的lpData。
目标程序接收到WM_COPYDATA消息后,判断COPYDATASTRUCT的dwData是否是自定义消息编号,是的话就处理。
1、发送接收程序都定义好要传递的消息,并且在窗体创建事件里边进行注册:
private
StartMsg: UINT; //开始录音消息
StartMsg := RegisterWindowMessage('StartRecord');
2、发送程序发送:
procedure TForm3.BtnStartClick(Sender: TObject);
var
lHandle: THandle;
ret: integer;
cpStruct: COPYDATASTRUCT;
begin
lHandle := FindWindow('TFrmRecord', nil);
//log('找到窗口句柄:' + inttostr(lHandle));
if lHandle > 0 then
begin
//log('向目标窗口发送开始录音消息');
cpStruct.dwData := StartMsg;
cpStruct.cbData := length('123.wav');
cpStruct.lpData := pchar('123.wav');
ret := SendMessage(lHandle, WM_COPYDATA, 0, Integer(@cpStruct));
memLog.Lines.Add('发送消息返回值:' + inttostr(ret));
end;
end;
3、接收程序处理消息:
protected
//处理开始录音、结束录音消息
procedure WndProc(var msg: TMessage); override;
procedure TFrmRecord.WndProc(var msg: TMessage);
var
lFileName: pchar;
Rec: TWavRecord;
lStr: String;
begin
if msg.Msg = WM_COPYDATA then
begin
if PCopyDataStruct(msg.LParam)^.dwData = StartMsg then
begin
log('收到开始录音消息');
lStr := StrPas(PCopyDataStruct(msg.LParam)^.lpData);
lStr := copy(lStr, 1, PCopyDataStruct(msg.LParam)^.cbData);
EdtFile.Text := ExtractFilePath(application.ExeName) + 'record\' + lStr;
log('录音文件名称:' + lStr);
if BtnStart.Enabled then
BtnStart.Click;
end;
end
else
if msg.Msg = EndMsg then
begin
if BtnStop.Enabled then
begin
log('收到停止录音消息:' + inttostr(EndMsg));
BtnStop.Click;
end;
end;
inherited;
end;