PostMessage、SendMessage、字符串、多线程???

okmnji79513 2009-12-22 02:12:22
如何用PostMessage、SendMessage传送 字符串 或者 结构体??

例如:
TMyRecord=record
s:string;
end;

var s:string;
MyR:TMyRecord;

基本是这样发送:
PostMessage(窗口handle , 某消息 , 0 , integer(s));
PostMessage(窗口handle , 某消息 , 0 , integer(MyR));

但是看到有 字符串 接收不全 的情况。

我要问如下几种情况:
1、发消息 和 接消息 在 同一 线程中

procedure TForm1.My(var msg:TMessage);//message WM_My;
var pc:PChar;
My:TMyRecord;
s:string;
begin
if msg.LParam=5 then
begin
My:=TMyRecord(msg.WParam);
Memo1.Lines.Add('My.s : '+My.s);
end;
if msg.LParam=6 then
begin
s:=string(msg.WParam);
Memo1.Lines.Add('s : '+s);
end;
end;

procedure TForm1.Button11Click(Sender: TObject);
var tt:TMyRecord;
begin
tt.s:='s2343243';
PostMessage(handle,WM_My,integer(tt),5);
end;

procedure TForm1.Button12Click(Sender: TObject);
var s:string;
begin
s:='jkchjvb';
PostMessage(handle,WM_My,integer(s),6);
end;


2、发消息 和 接消息 在 同一进程的 不同线程 中
主线程 接收消息:

procedure TForm1.My(var msg:TMessage);//message WM_My;
var pc:PChar;
My:TMyRecord;
s:string;
begin
if msg.LParam=5 then
begin
My:=TMyRecord(msg.WParam);
Memo1.Lines.Add('My.s : '+My.s);
end;
if msg.LParam=6 then
begin
s:=string(msg.WParam);
Memo1.Lines.Add('s : '+s);
end;
end;


子线程 发送消息:

procedure TAAThread.Execute;
var tt:TMyRecord;
begin
tt.s:='s2343243';
PostMessage(handle,WM_My,integer(tt),5);
end;

//或者 子线程 发 字符串
procedure TAAThread.Execute;
var s:string;
begin
s:='jkchjvb';
PostMessage(handle,WM_My,integer(s),6);
end;


以上两种情况,会不会 在字符串比较长 或 结构体比较大 时,接收的信息不全??如果会产生 接收不全 的情况,那如何避免其发生? ------①
请注意:我上面代码中用到的 tt , s 都是局部变量,没有用全局变量。

把postmessage换成sendmessage情况又如何呢? ------②
sendmessage能保证 “2、发消息 和 接消息 在 同一进程的 不同线程 中” 的 局部变量值 被完全接收吗? ------③
子线程 用sendmessage发消息时(如2、中的代码,PostMessage改成SendMessage),如果消息处理过程比较耗时,在消息处理完成前,子线程 处于上面状态?阻塞?挂起?消耗CPU时间片吗?消耗系统资源吗? ------④

对①②③④处的几个问题,进行解答,谢谢。
...全文
549 8 打赏 收藏 举报
写回复
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
okmnji79513 2009-12-23
  • 打赏
  • 举报
回复
谢谢 各位。 结了。
mdejtod 2009-12-22
  • 打赏
  • 举报
回复
如果给另一个程序发消息呢
使用wm_copydata 发送,
idecl 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 wzwcn 的回复:]
不管在同一线程还是不同线程都是可以通过消息发送数据的,我就经常这么干。你上面发结构消息不全的原因是:
var tt:TMyRecord;
begin
  tt.s:='s2343243';
  PostMessage(handle,WM_My,integer(tt),5);
end;

这样当然不全,因为参数只能是一个integer,你这样发只能发4个字节,所以你要改成发指针,比如:
var tt:TMyRecord;
begin
  tt.s:='s2343243';
  PostMessage(handle,WM_My,integer(@tt),5);
end;

接收的时候当然也不用能你原来的方法:My:=TMyRecord(msg.WParam);这样取回来了,也要把TMyRecord声明成指针:
type
  PMyRecord=^TMyRecord;
var
My:PMyRecord;
my:=PMyRecord(msg.WParam);

这样数据就全了。不过还有个问题,因为你的这个var tt:TMyRecord;是放过程里的,事实上过程一持行完tt就会被释放了。所以你要自己分配内存,new一个指针,等那边接收完再dispose,这样就没问题了
[/Quote]

如果给另一个程序发消息呢?内存地址不一样,发指针就要报错
hjkto 2009-12-22
  • 打赏
  • 举报
回复
学习
ok1411 2009-12-22
  • 打赏
  • 举报
回复
学习
wzwcn 2009-12-22
  • 打赏
  • 举报
回复
不管在同一线程还是不同线程都是可以通过消息发送数据的,我就经常这么干。你上面发结构消息不全的原因是:
var tt:TMyRecord;
begin
tt.s:='s2343243';
PostMessage(handle,WM_My,integer(tt),5);
end;

这样当然不全,因为参数只能是一个integer,你这样发只能发4个字节,所以你要改成发指针,比如:
var tt:TMyRecord;
begin
tt.s:='s2343243';
PostMessage(handle,WM_My,integer(@tt),5);
end;

接收的时候当然也不用能你原来的方法:My:=TMyRecord(msg.WParam);这样取回来了,也要把TMyRecord声明成指针:
type
PMyRecord=^TMyRecord;
var
My:PMyRecord;
my:=PMyRecord(msg.WParam);

这样数据就全了。不过还有个问题,因为你的这个var tt:TMyRecord;是放过程里的,事实上过程一持行完tt就会被释放了。所以你要自己分配内存,new一个指针,等那边接收完再dispose,这样就没问题了
idecl 2009-12-22
  • 打赏
  • 举报
回复
如果在不同线程内。最好用PostThreadMessage代替PostMessage
------④ 子线程挂起
bdmh 2009-12-22
  • 打赏
  • 举报
回复
本进程中传递字符串可以直接传递,但在跨进程中传递字符串要使用WMCOPYData消息
发帖
Windows SDK/API

1177

社区成员

Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
帖子事件
创建了帖子
2009-12-22 02:12
社区公告
暂无公告