The*_*ude 2 delphi string pointers delphi-2010
我需要构造一个字符串并通过它发送它PostMessage,即.
FileName := String_1 + String_2 + String_3;
PostMessage(FWndHandle, WM_BLA_BLA, NotifyData^.Action, LParam(FileName));
Run Code Online (Sandbox Code Playgroud)
但有些东西不起作用.另外,FileName是PChar.代码如下所示:
var
FileName : PChar;
Directory_Str : String;
AnotherString : String;
begin
// Get memory for filename and fill it with data
GetMem(FileName, NotifyData^.FileNameLength + SizeOf(WideChar));
Move(NotifyData^.FileName, Pointer(FileName)^, NotifyData^.FileNameLength);
PWord(Cardinal(FileName) + NotifyData^.FileNameLength)^ := 0;
// TODO: Contact string before sending message
// FileName := AnotherString + Directory_Str + FileName;
PostMessage(FWndHandle, WM_BLA_BLA, NotifyData^.Action, LParam(FileName));
...
end;
Run Code Online (Sandbox Code Playgroud)
现在我需要FileName在调用之前将另一个字符串联系到变量PostMessage,即.
FileName := AnotherString + Directory_Str + FileName;
PostMessage(FWndHandle, WM_BLA_BLA, NotifyData^.Action, LParam(FileName));
Run Code Online (Sandbox Code Playgroud)
如果FileName是一个字符串,这将起作用,这不是这里的情况.
任何人都知道如何用PChar做到这一点?我试过这些方法,有时会工作但总会在最后打破一些东西:
StrPCopy(FileName, FDirectory + String(FileName));
Run Code Online (Sandbox Code Playgroud)
要么
FileName := PChar(AnotherString + Directory_Str + FileName);
Run Code Online (Sandbox Code Playgroud)
您不能轻易使用PostMessage通过引用传递的数据.原因是PostMessage异步执行并且您需要保持正在传递的内存,直到其收件人处理了该消息.我想这就是你的GetMem代码背后的东西.
显然,这仅适用于同一过程.并且您还会发现Windows不允许您使用PostMessage任何接收指针的消息.例如,PostMessage与WM_SETTEXT总是失败.您只能希望使用用户定义的消息执行此操作.当然,您需要在接收消息的代码中释放内存.
我将假设您正在使用允许发送字符串的用户定义消息PostMessage.在这种情况下,您已经有了解决方案.使用字符串变量进行连接,然后使用答案中的第一个代码块.
虽然你可以这样做得更清洁:
function HeapAllocatedPChar(const Value: string): PChar;
var
bufferSize: Integer;
begin
bufferSize := (Length(Value)+1)*SizeOf(Char);
GetMem(Result, bufferSize);
Move(PChar(Value)^, Result^, bufferSize);
end;
procedure PostString(Window: HWND; Msg: UINT; wParam: WPARAM;
const Value: string);
var
P: PChar;
begin
P := HeapAllocatedPChar(Value);
if not PostMessage(Window, Msg, wParam, LPARAM(P)) then
FreeMem(P);
end;
Run Code Online (Sandbox Code Playgroud)
你可以像这样调用这个程序:
PostString(FWndHandle, WM_BLA_BLA, NotifyData^.Action, FDirectory + FileName);
Run Code Online (Sandbox Code Playgroud)
您当前的代码失败,因为:
StrPCopy,不要为更长的字符串分配任何内存.PChar(AnotherString + Directory_Str + FileName)你陷入了你试图避免的陷阱GetMem.这是一个本地字符串,在处理消息时已被解除分配.如果您可以找到解决问题的方法而不使用PostMessage传递字符串,那么这可能比所有这些复杂性更可取.
请参阅David的答案,了解代码失败的原因.
我总是定义一个用于通过PostMessage操作分配字符串的类.没有泄漏的风险,并且可以通过更多信息轻松扩展.
Type
TMyMessage = class
msg : String;
Constructor Create(aMessage : String);
end;
// Sending the message
var
myMsg : TMyMessage;
...
myMsg := TMyMessage.Create('A message');
if not PostMessage(someHandle,WM_something,WParam(myMsg),0)
then begin
myMsg.free;
... Take care of this condition if PostMessage fails !!
end;
// Receiving the message
procedure TSomeForm.GetMessage(var msg : TMessage);
var
aMsg : TMyMessage;
begin
...
aMsg := TMyMessage(msg.WParam);
try
...
// Do something with the message
finally
aMsg.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2700 次 |
| 最近记录: |