王朝网络
分享
 
 
 

Delphi7 从子线程中发送消息到主线程触发事件执行

王朝delphi·作者佚名  2006-05-27
宽屏版  字体: |||超大  

在对数据库的操作时,有时要用一个子线程来进行后台的数据操作。比如说数据备份,转档什么的。在主窗口还能同是进行其它操作。而有时后台每处理一个数据文件,要向主窗口发送消息,让主窗口实时显示处理进度在窗口上(可视),同时进行日志处理等。我用的是下面的方法:

[1]用到的API函数:

RegisterWindowsMessage

----------------------

函数功能:该函数定义一个新的窗口消息,该消息确保在系统中是唯一的。返回的消息值可在调用函数SendMessage或PostMessage时使用。

function RegisterWindowMessage(lpString: PChar): UINT; stdcall;

SendNotifyMessage

----------------------

函数功能:该函数将指定的消息发送到一个窗口。

如果该窗口是由调用线程创建的;此函数为该窗口调用窗口程序,

并等待窗口程序处理完消息后再返回。

如果该窗口是由不同的线程创建的,此函数将消息传给该窗口程序,

并立即返回,不等待窗口程序处理完消息。

SendNotifyMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);

BroadcastSystemMessage

----------------------

函数功能:该函数发送消息给指定的接受者。

接受者可以是一个应用程序、安装驱动器、网络驱动器、系统级设备驱动器

或这些系统组件的组合。

[2]过程:

type

TForm1 = class(TForm)

...............

...............

private

Msg: Cardinal;

protected

procedure WndProc(var Message: TMessage); override;

public

...............

...............

end;

var

Form1: TForm1;

MsgStrList: TStringList;

MsgStrLock : TCriticalSection;

implementation

uses ThreadCommunication_Unit;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

Msg := RegisterWindowMessage('wm_threadmsg');

MsgStrList := TStringList.Create;

end;

procedure TForm1.WndProc(var Message: TMessage);

begin

if Message.Msg = Msg then begin

MsgStrLock.Enter;

if MsgStrList.Count > 0 then begin

Caption := MsgStrList.Strings[0];

MsgStrList.Delete(0);

end;

MsgStrLock.Leave;

ShowMessage('收到消息了'+ inttostr(Message.Msg));

end

else begin

inherited;

end;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

TThreadCommunication.Create(Msg,Memo1);

end;

...............

...............

initialization

MsgStrLock := TCriticalSection.Create;

finalization

MsgStrLock.Free;

end.

一个子线程类的单元:

unit ThreadCommunication_Unit;

interface

uses

Classes,StdCtrls;

type

TThreadCommunicaiton = class(TThread)

private

FMsg : Cardinal;

FMemo: TMemo;

protected

procedure Execute; override;

procedure SendMsg;

public

constructor Create(aMsg:Cardinal;am:TMemo);virtual;

end;

implementation

uses Messages,Windows, Dialogs,SysUtils, ThreadMsg;

{ TThreadCommunicaiton }

constructor TThreadCommunicaiton.Create(aMsg: Cardinal; am:TMemo);

begin

inherited Create(True);

FMsg := aMsg;

FMemo:= am;

FreeOnTerminate :=True;

Resume;

end;

procedure TThreadCommunicaiton.Execute;

begin

Synchronize(SendMsg);

end;

procedure TThreadCommunicaiton.SendMsg;

var

M: TMessage;

B: DWord;

d: integer;

begin

{ Place thread code here }

sleep(50);

M.Msg := FMsg;

B := BSM_ALLCOMPONENTS;

MsgStrLock.Enter;

MsgStrList.Add('子线程子柄:'+inttostr(ThreadID)+ ' 用BroadcastSystemMessage发送');

d := MsgStrList.Count;

MsgStrLock.Leave;

BroadcastSystemMessage(BSF_POSTMESSAGE, @B , M.Msg, M.WParam, M.LParam );

FMemo.Lines.Add('子线程子柄:'+inttostr(ThreadID)+ ' 用BroadcastSystemMessage发送'+inttostr(d));

end;

end.

我在窗口上放有一Memo控件,可以显示一些信息。

同时我定义了一个全局的TStringList的变量,用于存在要从子线程传出的一些值。用BroadcaseSystemMessage发送消息,而消息号由创建子线程时传入。而消息号在FormCreate中用RegisterWindowsMessage定义,并获得一个消息号。

而消息触发后的事件处理写在WndProc中。

这里将子线程传出的字符串写入窗口的标题。

而TStringList的变量作为临界区使用, 因为当两个线程访问全局量时,为防止它们同时执行,需要使用线程同步。

用TCriticalSection进行操作。

Enter,进入临界区

Leave,离开临界区

这样可以正确的处理从子线程发来的消息。

如果是用SendNotifyMessage函数发送消息的话。

用法如下:

M.Msg := FMsg;

SendNotifyMessage(HWND_BROADCAST,M.Msg , M.WParam, M.LParam);

参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

由于是用SendNotifyMessage将消息发送到主窗口,而主窗口所在线程与调用线程是同一个线程,所以要等待窗口程序处理完消息后再返回。才会执行子线程中的:

FMemo.Lines.Add('子线程子柄:'+inttostr(ThreadID)+ ' 用SendNotifyMessage发送');

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有