多线程向窗口线程发送消息,传递结构指针,程序莫名奇妙就退出?高手请进!(100分)

  • 主题发起人 主题发起人 southbird
  • 开始时间 开始时间
S

southbird

Unregistered / Unconfirmed
GUEST, unregistred user!
在定时器中 循环建立同一个线程类的多个实例(10个以上),此线程会向窗口线程,用sendmessage 发送消息,
在 wParam 参数中传递了一个结构的地址,
type
Tmyrecd=record
name:array[0..99]of char;
value:array[0..59]of char;
end;

var Plock:^Tmyrecd ;
sendmessage(mainform.Handle ,WM_MYmessage,integer(Pblock),0)
在窗口类中自定义消息接收函数
procedure Tmainform.GetMessages(var messge:TMessage);message WM_MYmessage ;
var newblock:^Tmyrecd;
begin
newblock:=ptr(message.WParam) ;
// 取出 newblock^.name ,newblock^.value 显示;
end;
程序有时会告指针错误,有时无任何错误提示就退出?
为何?消息中传递指针本身是不稳定的吗?
该如何处理?
 
涉及指针的问题都要慎用,我看你软件的状况应是指针的问题。
 
把sendmessage换成postmessage(),效果可能要好,但是问题不在这
Plock是什么类型的变量,是全局还是线程中的变量?
 
有冲突,内存出错,退出
 
to 张无忌:线程中不能用PostMessage,否则会导致不可预料的结果。

线程中传递指针肯定是没问题的,但是要注意的是你的线程的写法,如果你的线程是自动
释放的话,你必须保证主窗体的消息处理事件在处理指针的时候线程没有释放,这样指
针指才是有效的,否则那个指针已经无效,你调用的时候自然就出错了。
没有看到你的全部代码,不知道是不是这个问题。
 
用PostMessage没有什么问题,问题是你要保证一些资源比如全局变量的安全,
比如,你的接到消息的处理过程最好不要修改和使用线程中全局变量的值。
 
TO 教父;
当然我的线程中用的不是postmessage;而是sendmessage,系统它会等待系统返回
帮助中介绍如下:
This function sends the specified message to the window procedure of the
indicated window, and does not return until the called window procedure
has processed the message. If the specified window belongs to the calling
thread, that window's window procedure is called immediately as a subroutine.
However, if the window belongs to a different thread, Windows switches
to that thread, sending the message to the appropriate window procedure,
and the thread sending the message is blocked until the receiving thread
processes the message.
故在消息处理时,所传递的指针空间还是有效的!而且处理完后故意没有释放指针!
(多耗点内存而已)
至于是申请的指针是全局变量还是局部变量,应该都不是问题,
应为都是在同一个进程内,用指针的方式应该都能访问得到!?(此观点是否正确?)
我是在线程内申请的指针空间!
在代码实现方法上应该是没有问题的,因为正常运行时可以看到正确结果,
只是压力性能上不好,线程多了后就会告指针错误或程序直接退出!
我想肯定是在消息接收时,取指针内容的时候有问题!
到底线程多了后,消息接收处理时,为什么会出错?难道参数message.WParam被
异常改变了?导致取指针匹配错误?
教父有何高见?不妨再指点一二?
 
const WM_ADDUSERTOLIST =WM_User +1;
...
...
private
{ Private declarations }
procedure DOWM_AddUserToList(var Msg: TWMCopyData);message WM_ADDUSERTOLIST;
procedure MessageSend(const MsgStr: String);
.....
.....
procedure TForm1.DOWM_AddUserToList(var Msg: TWMCopyData);
var
Buffer: String;
begin
Buffer :=StrPas(Msg.CopyDataStruct^.lpData);
ShowMessage(Buffer);
end;

procedure TForm1.MessageSend(const MsgStr: String);
var
cpDataStruct: TCopyDataStruct;
begin
FillChar(cpDataStruct, SizeOf(TCopyDataStruct), Char(0));
cpDataStruct.lpData :=PChar(MsgStr);
SendMessage(Handle, WM_ADDUSERTOLIST, 0, LParam(@cpDataStruct));
end;

 
后退
顶部