要使用 QWorker 进行后台线程作业,我们要做的第一件事,就是当然就是要引用 QWorker 这个单元,在 C++ Builder 中,要包含 qworker.hpp。
【Delphi】
uses qworker;
【C++ Builder】
#include "qworker.hpp"
在 C++ Builder 中,我们还需要以下两步之一:
(1)、将 qworker 相关的 .pas 加入到当前工程中,这样 C++ Builder 就会自动编译生成 qworker.hpp,并在链接时将 qworker.obj 链接到程序中。
(2)、先建立一个临时的工程,将 qworker 相关的 .pas 加入后编译生成的 *.hpp 复制到 C++ Builder 的Include 目录下,将*.obj 复制到 Lib 目录下,这样以后只需要直接包含 qworker.hpp 就可以了。
做好上面的准备工作后,我们就可以做一个最简单的作业了。好吧,我们的作业只干一件事,显示一个经典的的“Hello,world!”。
首先添加一个主线程作业处理函数 DoHelloworld,这个函数之所以要求运行在主线程,是因为用 ShowMessage 是 VCL 函数,它不是线程安全的,所以要运行在主线程中。然后我们在窗体上添加一个按钮 Button1,然后设置其 OnClick 事件来触发作业处理函数。完成后的代码如下:
【Delphi】
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,qworker, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } procedure DoHelloworld(AJob:PQJob); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject); begin Workers.Post(DoHelloworld,nil,True); end; procedure TForm1.DoHelloworld(AJob: PQJob); begin ShowMessage('Hello,world'); end; end.
【C++ Builder】
(1)头文件:Unit1.h
//--------------------------------------------------------------------------- #ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include <System.Classes.hpp> #include <Vcl.Controls.hpp> #include <Vcl.StdCtrls.hpp> #include <Vcl.Forms.hpp> #include "qworker.hpp" //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TButton *Button1; void __fastcall Button1Click(TObject *Sender); private: // User declarations void __fastcall DoHelloworld(PQJob AJob); public: // User declarations __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif
(2)主文件:Unit1.cpp
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::DoHelloworld(PQJob AJob) { ShowMessage("Hello,world"); } void __fastcall TForm1::Button1Click(TObject *Sender) { Workers->Post(DoHelloworld,NULL,true); } //---------------------------------------------------------------------------
看看程序的运行效果:
好了,效果看到了。我们看看刚才用到的 Post 函数的声明:
【Delphi】
function Post(AProc: TQJobProc; AData: Pointer;ARunInMainThread: Boolean = False;AFreeType: TQJobDataFreeType = jdfFreeByUser): IntPtr; overload;
【C++ Builder】
NativeInt __fastcall Post(TQJobProc AProc, void * AData, bool ARunInMainThread = false, TQJobDataFreeType AFreeType = (TQJobDataFreeType)(0x0))/* overload */;
这个函数的作业是投寄一个需要立即在后台执行的作业,如果成功,返回一个作业的句柄实例,如果失败,返回0。其参数含义如下:
- AProc :要执行的作业处理函数
- AData :作业附加的用户数据指针,其具体含义由作业处理函数自行解析,可以用来传递作业需要的参数
- ARunInMainThread:作业是否要求在主线程中执行,如果作业需要在主线程执行,则设置为true,如果不需要,则设置为 false
好了,这个最经典的HelloWorld就此搞定,是不是觉得很简单?好复杂?!算了,编程不适合你,开玩笑:)