转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Delphi7 从子线程中发送消息到主线程触发事件执行         ★★★★

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

作者:闵涛 文章来源:闵涛的学习笔记 点击数:847 更新时间:2009/4/23 18:30:23

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

[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发送'''');





[聊天工具]让IE 7也用上鼠标手势  [常用软件]IE 7出炉,Firefox 2当道.谁才是“王者”?
[常用软件]绕过WGA安装IE 7 Beta3 5450  [VB.NET程序]VB.NET实现DirectSound9 (7) 录音
[VB.NET程序]DirectX 7 编程初步  [VB.NET程序]VB程序员眼中的C# 7
[Delphi程序]DELPHI7 如何在编写可视组件中传递一个事件到组件…  [Delphi程序]Delphi7 的 WebService 与 数据库
[Delphi程序]Delphi 7 中使用RAVE报表(一)  [Delphi程序]Delphi 7 中使用RAVE报表(二)
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台