亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

Delphi關于線程的消息處理

2019-11-18 18:03:06
字體:
來源:轉載
供稿:網友
 

在平時寫程序時,總是碰到窗體(TForm)與線程(TThread)消息通信問題。令人煩惱的是窗體不能向線程(TThread)發送消息(線程沒有窗口句柄)。經過幾天的折騰,想出二種解決方案,拿出來跟大家探討探討。

第一。我們知道VC++ 中的MFC類庫是自已封裝了消息處理(BEGINMESSAGE, ENDMESSAGE),在MFC中對消息的處理是通過建立一張消息映射表,而把方法(function)或過程(PRocedure)的地址保存到映射表里(消息處理實質上是方法或過程的調用),再加上一個消息分發機制,來實現消息的接收發送 <詳見VC++技術內幕>。所以我們只要為線程里建立一張消息映射表,并建立相應的消息分發機制。這樣就可以處理窗體發送到線程的消息。以下代碼是實現消息映射表和消息分發的類(詳見 <../消息處理設計(線程)1/MessageHandle.pas>

unit MessageHandle;

 

interface

uses messages,Classes,SysUtils,Dialogs;

 

const PMSG_BASE = $BE00;   //自定義消息基址;

      PMSG_NUM = 200;      //消息表大??;

 

{**自定義消息處理類

  *;功能 = 建立自定義消息表,處理線程之間

  *   以及與主窗體之間的自定義消息(宏觀)

*}

 

  //消息處理句柄

  TMessageHandle = procedure(var Message: TMessage) of Object;

 

  TPDispatcher = class(TObject)

  private

    //消息對應表(消息ID為數組下標);

    MessageHandles: array of TMessageHandle;

    //從消息ID得到數組ID

    function GetIndexFromMsgID(const aMessageID: cardinal): Integer;

  public

    constructor Create;

    destructor Destroy;

    //發送消息

    procedure SendMessage(var Message: TMessage); overload;

    //添加自定義消息到消息對應表;

    procedure AddHandle(const aMessageID: cardinal; aMessageHandle: TMessageHandle);

  end;

  //

 

implementation

 

{ TPDispatcher }

constructor TPDispatcher.Create;

var i: Integer;

begin

  SetLength(MessageHandles,PMSG_NUM);  //200個消息的消息對應表

  //初始化消息隊列;

  for i := 0 to Pred(PMSG_NUM) do

    MessageHandles[i] := nil;

end;

 

destructor TPDispatcher.Destroy;

begin

   {釋放消息對應表}

  FreeAndNil(MessageHandles);

end;

 

procedure TPDispatcher.AddHandle(const aMessageID: cardinal;

  aMessageHandle: TMessageHandle);

var tID: Integer;

begin

  tID := GetIndexFromMsgID(aMessageID);

  Assert((tID > 0) or (tID < Pred(PMSG_NUM)) );

  Assert(Assigned(aMessageHandle));

  MessageHandles[tID] := aMessageHandle;

end;

 

function TPDispatcher.GetIndexFromMsgID(const aMessageID: cardinal): Integer;

begin

  Result := aMessageID - PMSG_BASE;

end;

 

procedure TPDispatcher.SendMessage(var Message: TMessage);

var tID: Integer;

    tMsgHandle: TMessageHandle;

begin

  tID := GetIndexFromMsgID(Message.Msg);

  Assert((tID > 0) or (tID < Pred(PMSG_NUM)));

  tMsgHandle := MessageHandles[tID];

 

  if Assigned(tMsgHandle) then

    tMsgHandle(Message);

end;

現在我們只需要注冊一下自定義的消息,然后通過消息分發類(TPDispatcher),實現對線程消息的處理。代碼如下<詳見../消息處理設計(線程)1/test/unit1.pas>

Unit unit1

const

      {自定久線程消息}

      MY_MESSAGE2 = PMSG_BASE + 02; 

type

  TForm1 = class(TForm)

    AddMsgList: TButton;

    SendThead: TButton;

    sendForm: TButton;

    sendOther: TButton;

    procedure SendTheadClick(Sender: TObject);  //發送消息

    procedure FormCreate(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

  private

    Fdispatcher: TPDispatcher;  消息映射表類

    Fhandle: TPHandler;

    FThread:  TPTHread;  自定義線程類

  public

    { Public declarations }

  end;

 

var

  Form1: TForm1;

 

implementation

 

{$R *.dfm}

procedure TForm1.SendTheadClick(Sender: TObject);

var aMessage: TMessage;begin

    aMessage.Msg := MY_MESSAGE2;

    aMessage.WParam := 1;

    Fdispatcher.SendMessage(aMessage);

  end;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

  {創建消息映射表類}

  Fdispatcher := TPDispatcher.Create;

  Fhandle := TPHandler.Create;

  {創建線程}

    FThread := TPThread.Create(false);

  {向映射表中增加消息}

   Fdispatcher.AddHandle(MY_MESSAGE2,FThread.DoMessage);

end;

 

procedure TForm1.FormDestroy(Sender: TObject);

var i: Integer;

begin

  FreeAndNil(Fdispatcher);

  FreeAndNil(Fhandle);

  for i:= 0 to 3 do

    FreeAndNil(FThread[i]);

end;

 

第二。窗口可以處理消息是因為它有窗口句柄。為了使線程也能處理消息,我們可以通過為線程加上一個相應窗口類的窗口名柄。(源碼 <../消息處理設計(線程)2 / pThread.pas >中)

unit pThread;

 

interface

uses classes,sysutils,Windows,Messages,Dialogs;

const MY_MESSAGE1 = $BD00 + 01;

Type

{** 消息處理線程類

  *;功能 = 添加線程處理消息能力,

*}

  TPMsgThread = class(TThread)

  private

    //窗口句柄

    FWndHandle: HWND;

    //窗口數據信息

    FWndClass: WNDCLASS;

    //指向窗口回調函數的指針

    FObjectInstance: Pointer;

    //初始化窗口數據

    procedure InitWnd;

    //創建隱藏窗口

    procedure CreateWnd;

    //注冊隱藏窗口

    procedure RegistWnd;

    procedure DestroyWnd;

    //窗口回調函數

    procedure pWndProc(var Message: TMessage); virtual;

  protected

    procedure Execute; override;

    procedure DoTerminate; override;

  public

    constructor Create(CreateSuspended: Boolean); virtual;

    property WndHandle: HWND read FWndHandle write FWndHandle;

  end;

 

implementation

const WND_NAME = 'PY20';

{ TPMsgThread }

 

constructor TPMsgThread.Create(CreateSuspended: Boolean);

begin

  inherited Create(CreateSuspended);

  FWndHandle := Integer(nil);

  InitWnd;

  RegistWnd;

  CreateWnd;

end;

 

procedure TPMsgThread.CreateWnd;

begin

  if(WndHandle = Integer(nil)) then

    WndHandle := CreateWindow(FWndClass.lpszClassName, FWndClass.lpszClassName,

      WS_POPUP or WS_CAPTION or WS_CLipSIBLINGS or WS_SYSMENU

      or WS_MINIMIZEBOX,

      GetSystemMetrics(SM_CXSCREEN) div 2,

      GetSystemMetrics(SM_CYSCREEN) div 2,

      0, 0, 0, 0, FWndClass.hInstance, nil);

  //置換窗口回調函數

  SetWindowLong(WndHandle, GWL_WNDPROC, Longint(FObjectInstance));

end;

 

procedure TPMsgThread.DestroyWnd;

begin

  UnregisterClass(FWndClass.lpszClassName,FWndClass.hInstance);

  DestroyWindow(WndHandle);

end;

 

procedure TPMsgThread.DoTerminate;

begin

  inherited;

  DestroyWnd;

end;

 

procedure TPMsgThread.Execute;

begin

end;

 

procedure TPMsgThread.InitWnd;

begin

  FwndClass.lpszClassName := PChar(WND_NAME);

  FWndClass.hInstance := Handle;

  FWndClass.lpfnWndProc := @DefWindowProc;

end;

 

procedure TPMsgThread.pWndProc(var Message: TMessage);

begin

end;

 

procedure TPMsgThread.RegistWnd;

begin

  FObjectInstance := Classes.MakeObjectInstance(pWndProc);

  if(FWndClass.hInstance <> Integer(nil)) then

    RegisterClass(FWndClass);

end;


上一篇:Delphi控件制作技巧[二]

下一篇:Delphi控件制作技巧[一]

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲高清久久久久久| 55夜色66夜色国产精品视频| 亚洲成人网久久久| 日韩午夜在线视频| 欧美视频中文在线看| 美女久久久久久久| 亚洲国产精品高清久久久| 国产成人福利视频| 51ⅴ精品国产91久久久久久| 欧美色视频日本版| 欧美日韩爱爱视频| 国产热re99久久6国产精品| 欧美老少配视频| 4444欧美成人kkkk| 亚洲一级黄色片| 亚洲精品www久久久| 日av在线播放中文不卡| 国产999视频| 欧美一级片久久久久久久| 欧日韩不卡在线视频| 亚洲精品二三区| 久久精品2019中文字幕| 在线观看国产欧美| 国产原创欧美精品| 最近2019中文免费高清视频观看www99| 另类色图亚洲色图| 亚洲欧美日韩精品久久奇米色影视| 欧美激情亚洲激情| 韩曰欧美视频免费观看| 韩剧1988在线观看免费完整版| 欧美裸体xxxx极品少妇| 中文字幕欧美国内| 亚洲国产高清福利视频| 91亚洲精华国产精华| 韩国三级电影久久久久久| 亚洲国产91精品在线观看| 国产精品日韩av| 欧美一级片一区| 精品国产福利在线| 亚洲黄色在线观看| 欧美午夜www高清视频| 日韩国产精品亚洲а∨天堂免| 欧美亚洲免费电影| 亚洲japanese制服美女| 久久免费观看视频| 欧美性高潮在线| 亚洲成人激情视频| 在线一区二区日韩| 日韩欧美亚洲一二三区| 欧美自拍大量在线观看| 久久久久久久亚洲精品| 高清亚洲成在人网站天堂| 青青草精品毛片| 日本精品性网站在线观看| 国产激情久久久| 欧美激情手机在线视频| 欧美成人在线影院| 亚洲一区二区精品| yellow中文字幕久久| 中文字幕视频一区二区在线有码| 国产精品久久久久久久7电影| 欧美成人全部免费| 国产精品久久久久9999| 欧美成人剧情片在线观看| 精品久久久久久亚洲精品| 国产精品视频永久免费播放| 国产v综合v亚洲欧美久久| 日本19禁啪啪免费观看www| 性色av一区二区三区红粉影视| 欧美成人国产va精品日本一级| 韩国视频理论视频久久| 在线观看免费高清视频97| 色爱精品视频一区| 九九热这里只有在线精品视| 人九九综合九九宗合| 欧美色播在线播放| 国产精品欧美一区二区| 欧美黄色小视频| 国产三级精品网站| 久久97久久97精品免视看| 欧美另类极品videosbestfree| 国产精品亚洲美女av网站| 91av视频在线播放| 51久久精品夜色国产麻豆| 欧美中在线观看| 亚洲国产精品久久久久秋霞不卡| 国产精品久久久久久久久久三级| 欧美视频免费在线| 97超级碰碰碰| 日韩欧美中文字幕在线观看| 成年无码av片在线| 国产精品爽爽爽| 亚洲最大av网站| 国产精品视频一区国模私拍| 亚洲精品福利在线观看| 成人亲热视频网站| 4k岛国日韩精品**专区| 中文字幕视频一区二区在线有码| 91系列在线播放| 日韩视频―中文字幕| 7777kkkk成人观看| 国产性色av一区二区| 91超碰caoporn97人人| 亚洲欧洲日产国码av系列天堂| **欧美日韩vr在线| 欧美超级乱淫片喷水| 97香蕉久久夜色精品国产| 精品国产福利在线| 国产视频精品久久久| 欧美成人免费视频| 欧美激情视频网站| 黑人与娇小精品av专区| 欧美黑人视频一区| 国产欧美在线看| 91中文字幕一区| 91色精品视频在线| 疯狂做受xxxx欧美肥白少妇| 黄色精品在线看| 久久久久免费精品国产| 亚洲精品乱码久久久久久金桔影视| 日韩专区中文字幕| 久久国产精品影视| 欧美精品生活片| 7777精品久久久久久| 国产精品视频网址| 茄子视频成人在线| 狠狠色狠狠色综合日日小说| 成人av色在线观看| 伊人久久大香线蕉av一区二区| 国产精品一区二区久久国产| 97国产在线观看| 亚洲第一精品自拍| 国产又爽又黄的激情精品视频| 色多多国产成人永久免费网站| 伊人伊成久久人综合网站| 91久久国产精品91久久性色| 欧美成年人视频网站| 亚洲精品大尺度| 伊人久久精品视频| 国产精品劲爆视频| 91精品视频大全| 亚洲人成网站999久久久综合| 91免费看国产| 午夜精品福利在线观看| 国产精品一区二区3区| 久久五月情影视| 日韩成人小视频| 欧美性xxxx极品高清hd直播| 91免费福利视频| 精品日本高清在线播放| 日产精品久久久一区二区福利| 欧美丝袜一区二区三区| 国产一区二区三区日韩欧美| 57pao国产成人免费| 欧美日韩国产二区| 欧美激情一区二区三区成人| 久久久91精品国产| 中文字幕日韩精品在线观看| 久久久亚洲天堂| 国产日韩在线视频| 日韩av免费在线| 欧美性猛交xxxx久久久| 欧美激情视频在线免费观看 欧美视频免费一| 欧美色道久久88综合亚洲精品|