首页 > 代码库 > 在delphi线程中实现消息循环
在delphi线程中实现消息循环
http://delphi.cjcsoft.net//viewthread.php?tid=635
在delphi线程中实现消息循环
在delphi线程中实现消息循环
Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供.
Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供.
花了两天的事件研究了一下win32的消息系统,写了一个线程内消息循环的测试.
但是没有具体应用过,贴出来给有这方面需求的DFW参考一下.希望大家和我讨论.
{-----------------------------------------------------------------------------Unit Name: uMsgThreadAuthor: xwingeMail : xwing@263.net ; MSN : xwing1979@hotmail.comPurpose: Thread with message LoopHistory:2003-6-19, add function to Send Thread Message. ver 1.0 use Event List and waitforsingleObject your can use WindowMessage or ThreadMessage2003-6-18, Change to create a window to Recving message2003-6-17, Begin.-----------------------------------------------------------------------------}unit uMsgThread;interface{$WARN SYMBOL_DEPRECATED OFF}{$DEFINE USE_WINDOW_MESSAGE}uses Classes, windows, messages, forms, sysutils;type TMsgThread = class(TThread) private {$IFDEF USE_WINDOW_MESSAGE} FWinName : string; FMSGWin : HWND; {$ELSE} FEventList : TList; FCtlSect : TRTLCriticalSection; {$ENDIF} FException : Exception; fDoLoop : Boolean; FWaitHandle : THandle; {$IFDEF USE_WINDOW_MESSAGE} procedure MSGWinProc(var Message: TMessage); {$ELSE} procedure ClearSendMsgEvent; {$ENDIF} procedure SetDoLoop(const Value: Boolean); procedure WaitTerminate; protected Msg :tagMSG; procedure Execute; override; procedure HandleException; procedure DoHandleException;virtual; //Inherited the Method to process your own Message procedure DoProcessMsg(var Msg:TMessage);virtual; //if DoLoop = true then loop this procedure //Your can use the method to do some work needed loop. procedure DoMsgLoop;virtual; //Initialize Thread before begin message loop procedure DoInit;virtual; procedure DoUnInit;virtual; procedure PostMsg(Msg:Cardinal;wParam:Integer;lParam:Integer); //When Use SendMsg method Must not use Synchronize Method in ThreadLoop !!! //otherwise will caurse DeadLock procedure SendMsg(Msg:Cardinal;wParam:Integer;lParam:Integer); public constructor Create(Loop:Boolean=False;ThreadName: string=‘‘); destructor destroy;override; procedure AfterConstruction;override; //postMessage to Quit,and Free(if FreeOnTerminater = true) //can call this in thread loop, don‘t use terminate property. procedure QuitThread; //PostMessage to Quit and Wait, only call in MAIN THREAD procedure QuitThreadWait; //just like Application.processmessage. procedure ProcessMessage; //enable thread loop, no waitfor message property DoLoop: Boolean read fDoLoop Write SetDoLoop; end;implementation{ TMsgThread }{//////////////////////////////////////////////////////////////////////////////}constructor TMsgThread.Create(Loop:Boolean;ThreadName:string);begin {$IFDEF USE_WINDOW_MESSAGE} if ThreadName <> ‘‘ then FWinName := ThreadName else FWinName := ‘Thread Window‘; {$ELSE} FEventList := TList.Create; InitializeCriticalSection(fCtlSect); {$ENDIF} FWaitHandle := CreateEvent(nil, True, False, nil); FDoLoop := Loop; //default disable thread loop inherited Create(False); //Create thread FreeOnTerminate := True; //Thread quit and free object //Call resume Method in Constructor Method Resume; //Wait until thread Message Loop started WaitForSingleObject(FWaitHandle,INFINITE);end;{------------------------------------------------------------------------------}procedure TMsgThread.AfterConstruction;beginend;{------------------------------------------------------------------------------}destructor TMsgThread.destroy;begin {$IFDEF USE_WINDOW_MESSAGE} {$ELSE} FEventList.Free; DeleteCriticalSection(FCtlSect); {$ENDIF} inherited;end;{//////////////////////////////////////////////////////////////////////////////}procedure TMsgThread.Execute;var mRet:Boolean; aRet:Boolean; {$IFNDEF USE_WINDOW_MESSAGE} uMsg:TMessage; {$ENDIF}begin{$IFDEF USE_WINDOW_MESSAGE} FMSGWin := CreateWindow(‘STATIC‘,PChar(FWinName),WS_POPUP,0,0,0,0,0,0,hInstance,nil); SetWindowLong(FMSGWin, GWL_WNDPROC, Longint(MakeObjectInstance(MSGWinProc)));{$ELSE} PeekMessage(Msg,0,WM_USER,WM_USER,PM_NOREMOVE); //Force system alloc a msgQueue{$ENDIF} //notify Conctructor can returen. SetEvent(FWaitHandle); CloseHandle(FWaitHandle); mRet := True; try DoInit; while mRet do //Message Loop begin if fDoLoop then begin aRet := PeekMessage(Msg,0,0,0,PM_REMOVE); if aRet and (Msg.message <> WM_QUIT) then begin {$IFDEF USE_WINDOW_MESSAGE} TranslateMessage(Msg); DispatchMessage(Msg); {$ELSE} uMsg.Msg := Msg.message; uMsg.wParam := Msg.wParam; uMsg.lParam := Msg.lParam; DoProcessMsg(uMsg); {$ENDIF} if Msg.message = WM_QUIT then mRet := False; end; {$IFNDEF USE_WINDOW_MESSAGE} ClearSendMsgEvent; //Clear SendMessage Event {$ENDIF} DoMsgLoop; end else begin mRet := GetMessage(Msg,0,0,0); if mRet then begin {$IFDEF USE_WINDOW_MESSAGE} TranslateMessage(Msg); DispatchMessage(Msg); {$ELSE} uMsg.Msg := Msg.message; uMsg.wParam := Msg.wParam; uMsg.lParam := Msg.lParam; DoProcessMsg(uMsg); ClearSendMsgEvent; //Clear SendMessage Event {$ENDIF} end; end; end; DoUnInit; {$IFDEF USE_WINDOW_MESSAGE} DestroyWindow(FMSGWin); FreeObjectInstance(Pointer(GetWindowLong(FMSGWin, GWL_WNDPROC))); {$ENDIF} except HandleException; end;end;{------------------------------------------------------------------------------}{$IFNDEF USE_WINDOW_MESSAGE}procedure TMsgThread.ClearSendMsgEvent;var aEvent:PHandle;begin EnterCriticalSection(FCtlSect); try if FEventList.Count <> 0 then begin aEvent := FEventList.Items[0]; if aEvent <> nil then begin SetEvent(aEvent^); CloseHandle(aEvent^); Dispose(aEvent); end; FEventList.Delete(0); end; finally LeaveCriticalSection(FCtlSect); end;end;{$ENDIF}{------------------------------------------------------------------------------}procedure TMsgThread.HandleException;begin FException := Exception(ExceptObject); //Get Current Exception object try if not (FException is EAbort) then inherited Synchronize(DoHandleException); finally FException := nil; end;end;{------------------------------------------------------------------------------}procedure TMsgThread.DoHandleException;begin if FException is Exception then Application.ShowException(FException) else SysUtils.ShowException(FException, nil);end;{//////////////////////////////////////////////////////////////////////////////}{$IFDEF USE_WINDOW_MESSAGE}procedure TMsgThread.MSGWinProc(var Message: TMessage);begin DoProcessMsg(Message); with Message do Result:=DefWindowProc(FMSGWin,Msg,wParam,lParam);end;{$ENDIF}{------------------------------------------------------------------------------}procedure TMsgThread.DoProcessMsg(var Msg:TMessage);beginend;{------------------------------------------------------------------------------}procedure TMsgThread.ProcessMessage;{$IFNDEF USE_WINDOW_MESSAGE}var uMsg:TMessage;{$ENDIF}begin while PeekMessage(Msg,0,0,0,PM_REMOVE) do if Msg.message <> WM_QUIT then begin {$IFDEF USE_WINDOW_MESSAGE} TranslateMessage(Msg); DispatchMessage(msg); {$ELSE} uMsg.Msg := Msg.message; uMsg.wParam := Msg.wParam; uMsg.lParam := Msg.lParam; DoProcessMsg(uMsg); {$ENDIF} end;end;{//////////////////////////////////////////////////////////////////////////////}procedure TMsgThread.DoInit;beginend;procedure TMsgThread.DoUnInit;beginend;procedure TMsgThread.DoMsgLoop;begin Sleep(1);end;{//////////////////////////////////////////////////////////////////////////////}procedure TMsgThread.QuitThread;begin {$IFDEF USE_WINDOW_MESSAGE} PostMessage(FMSGWin,WM_QUIT,0,0); {$ELSE} PostThreadMessage(ThreadID,WM_QUIT,0,0); {$ENDIF}end;{------------------------------------------------------------------------------}procedure TMsgThread.QuitThreadWait;begin QuitThread; WaitTerminate;end;{------------------------------------------------------------------------------}procedure TMsgThread.SetDoLoop(const Value: Boolean);begin if Value = http://www.mamicode.com/fDoLoop then Exit; fDoLoop := Value; if fDoLoop then PostMsg(WM_USER,0,0);end;{------------------------------------------------------------------------------}//Can only call this method in MAIN Thread!!procedure TMsgThread.WaitTerminate;var xStart:Cardinal;begin xStart:=GetTickCount; try //EnableWindow(Application.Handle,False); while WaitForSingleObject(Handle, 10) = WAIT_TIMEOUT do begin Application.ProcessMessages; if GetTickCount > (xStart + 4000) then begin TerminateThread(Handle, 0); Beep; Break; end; end; finally //EnableWindow(Application.Handle,True); end;end;{------------------------------------------------------------------------------}procedure TMsgThread.PostMsg(Msg: Cardinal; wParam, lParam: Integer);begin {$IFDEF USE_WINDOW_MESSAGE} postMessage(FMSGWin,Msg,wParam,lParam); {$ELSE} EnterCriticalSection(FCtlSect); try FEventList.Add(nil); PostThreadMessage(ThreadID,Msg,wParam,lParam); finally LeaveCriticalSection(FCtlSect); end; {$ENDIF}end;{------------------------------------------------------------------------------}procedure TMsgThread.SendMsg(Msg: Cardinal; wParam, lParam: Integer);{$IFNDEF USE_WINDOW_MESSAGE}var aEvent:PHandle;{$ENDIF}begin {$IFDEF USE_WINDOW_MESSAGE} SendMessage(FMSGWin,Msg,wParam,lParam); {$ELSE} EnterCriticalSection(FCtlSect); try New(aEvent); aEvent^ := CreateEvent(nil, True, False, nil); FEventList.Add(aEvent); PostThreadMessage(ThreadID,Msg,wParam,lParam); finally LeaveCriticalSection(FCtlSect); end; WaitForSingleObject(aEvent^,INFINITE); {$ENDIF}end;end.
我参考了一下msdn,还有windows核心编程. 写了一个类来封装这个功能,不知道对不对.
里面使用了两个方法,一个使用一个隐含窗体来处理消息
还有一个是直接使用thread的消息队列来处理,但是这个时候sendmessage无法工作,
所以我自己设想了一个方法,虽然不完全达到了要求但是我简单测试了一下,好像还能工作.
切换两种工作方式要修改编译条件
{$DEFINE USE_WINDOW_MESSAGE} 使用隐含窗体来处理消息
{-$DEFINE USE_WINDOW_MESSAGE} 使用线程消息队列来处理消息
还有我想要等待线程开始进行消息循环的时候create函数才返回.
但是现在好像还没有这样(用一个事件来处理).只是开始进入了threadexecute函数,线程的create就返回了.可能会出问题.
通过设置 DoLoop属性可以设定线程是否循环(不阻塞等待消息),这样派生类线程在循环做一些其他事情的同时还可以接受消息. 例如:
派生类里面循环发送缓冲区的数据,还可以响应其他线程发送过来的消息(如停止,启动,退出,等等)
重新修改了一下,现在用起来基本没有问题了。
{ ----------------------------------------------------------------------------- Unit Name: uMsgThread Author: xwing eMail : xwing@263.net ; MSN : xwing1979@hotmail.com Purpose: Thread with message Loop History: 2003-7-15 Write thread class without use delphi own TThread. 2003-6-19, add function to Send Thread Message. ver 1.0 use Event List and waitforsingleObject your can use WindowMessage or ThreadMessage 2003-6-18, Change to create a window to Recving message 2003-6-17, Begin. ----------------------------------------------------------------------------- }unit uMsgThread;interface{$WARN SYMBOL_DEPRECATED OFF}{$DEFINE USE_WINDOW_MESSAGE}uses Classes, windows, messages, forms, sysutils;const NM_EXECPROC = $8FFF;type EMsgThreadErr = class( Exception ); TMsgThreadMethod = procedure of object; TMsgThread = class private SyncWindow : HWND; FMethod : TMsgThreadMethod; procedure SyncWindowProc( var Message : TMessage ); private m_hThread : THandle; threadid : DWORD;{$IFDEF USE_WINDOW_MESSAGE} FWinName : string; FMSGWin : HWND;{$ELSE} FEventList : TList; FCtlSect : TRTLCriticalSection;{$ENDIF} FException : Exception; fDoLoop : Boolean; FWaitHandle : THandle;{$IFDEF USE_WINDOW_MESSAGE} procedure MSGWinProc( var Message : TMessage );{$ELSE} procedure ClearSendMsgEvent;{$ENDIF} procedure SetDoLoop( const Value : Boolean ); procedure Execute; protected Msg : tagMSG;{$IFNDEF USE_WINDOW_MESSAGE} uMsg : TMessage; fSendMsgComp : THandle;{$ENDIF} procedure HandleException; procedure DoHandleException; virtual; // Inherited the Method to process your own Message procedure DoProcessMsg( var Msg : TMessage ); virtual; // if DoLoop = true then loop this procedure // Your can use the method to do some work needed loop. procedure DoMsgLoop; virtual; // Initialize Thread before begin message loop procedure DoInit; virtual; procedure DoUnInit; virtual; procedure PostMsg( Msg : Cardinal; wParam : Integer; lParam : Integer ); // When Use SendMsg method Must not use Synchronize Method in ThreadLoop !!! // otherwise will caurse DeadLock function SendMsg( Msg : Cardinal; wParam : Integer; lParam : Integer ) : Integer; public constructor Create( Loop : Boolean = False; ThreadName : string = ‘‘ ); destructor destroy; override; // Return TRUE if the thread exists. FALSE otherwise function ThreadExists : BOOL; procedure Synchronize( syncMethod : TMsgThreadMethod ); function WaitFor : Longword; function WaitTimeOut( timeout : DWORD = 4000 ) : Longword; // postMessage to Quit,and Free(if FreeOnTerminater = true) // can call this in thread loop, don‘t use terminate property. procedure QuitThread; // just like Application.processmessage. procedure ProcessMessage; // enable thread loop, no waitfor message property DoLoop : Boolean read fDoLoop write SetDoLoop; end;implementationfunction msgThdInitialThreadProc( pv : Pointer ) : DWORD; stdcall;var obj : TMsgThread;begin obj := TMsgThread( pv ); obj.Execute; Result := 0;end;{ TMsgThread }{ ////////////////////////////////////////////////////////////////////////////// }constructor TMsgThread.Create( Loop : Boolean; ThreadName : string );begin{$IFDEF USE_WINDOW_MESSAGE} if ThreadName <> ‘‘ then FWinName := ThreadName else FWinName := ‘Thread Window‘;{$ELSE} FEventList := TList.Create; InitializeCriticalSection( FCtlSect ); fSendMsgComp := CreateEvent( nil, True, False, nil );{$ENDIF}
fDoLoop := Loop; // default disable thread loop // Create a Window for sync method SyncWindow := CreateWindow( ‘STATIC‘, ‘SyncWindow‘, WS_POPUP, 0, 0, 0, 0, 0, 0, hInstance, nil ); SetWindowLong( SyncWindow, GWL_WNDPROC, Longint( MakeObjectInstance( SyncWindowProc ) ) ); FWaitHandle := CreateEvent( nil, True, False, nil ); // Create Thread m_hThread := CreateThread( nil, 0, @msgThdInitialThreadProc, Self, 0, threadid ); if m_hThread = 0 then raise EMsgThreadErr.Create( ‘不能创建线程。‘ ); // Wait until thread Message Loop started WaitForSingleObject( FWaitHandle, INFINITE );end;{ ------------------------------------------------------------------------------ }destructor TMsgThread.destroy;begin if m_hThread <> 0 then QuitThread; WaitFor; // Free Sync Window DestroyWindow( SyncWindow ); FreeObjectInstance( Pointer( GetWindowLong( SyncWindow, GWL_WNDPROC ) ) );{$IFDEF USE_WINDOW_MESSAGE}
{$ELSE} FEventList.Free; DeleteCriticalSection( FCtlSect ); CloseHandle( fSendMsgComp );{$ENDIF}
inherited;end;{ ////////////////////////////////////////////////////////////////////////////// }procedure TMsgThread.Execute;var mRet : Boolean; aRet : Boolean;begin{$IFDEF USE_WINDOW_MESSAGE} FMSGWin := CreateWindow( ‘STATIC‘, PChar( FWinName ), WS_POPUP, 0, 0, 0, 0, 0, 0, hInstance, nil ); SetWindowLong( FMSGWin, GWL_WNDPROC, Longint( MakeObjectInstance( MSGWinProc ) ) );{$ELSE} PeekMessage( Msg, 0, WM_USER, WM_USER, PM_NOREMOVE ); // Force system alloc a msgQueue{$ENDIF}
mRet := True; try DoInit; // notify Conctructor can returen. SetEvent( FWaitHandle ); CloseHandle( FWaitHandle ); while mRet do // Message Loop begin if fDoLoop then begin aRet := PeekMessage( Msg, 0, 0, 0, PM_REMOVE ); if aRet and ( Msg.Message <> WM_QUIT ) then begin{$IFDEF USE_WINDOW_MESSAGE} TranslateMessage( Msg ); DispatchMessage( Msg );{$ELSE} uMsg.Msg := Msg.Message; uMsg.wParam := Msg.wParam; uMsg.lParam := Msg.lParam; DoProcessMsg( uMsg );{$ENDIF} if Msg.Message = WM_QUIT then mRet := False; end;{$IFNDEF USE_WINDOW_MESSAGE} ClearSendMsgEvent; // Clear SendMessage Event{$ENDIF} DoMsgLoop; end else begin mRet := GetMessage( Msg, 0, 0, 0 ); if mRet then begin{$IFDEF USE_WINDOW_MESSAGE} TranslateMessage( Msg ); DispatchMessage( Msg );{$ELSE} uMsg.Msg := Msg.Message; uMsg.wParam := Msg.wParam; uMsg.lParam := Msg.lParam; DoProcessMsg( uMsg ); ClearSendMsgEvent; // Clear SendMessage Event{$ENDIF} end; end; end; DoUnInit;{$IFDEF USE_WINDOW_MESSAGE} DestroyWindow( FMSGWin ); FreeObjectInstance( Pointer( GetWindowLong( FMSGWin, GWL_WNDPROC ) ) );{$ENDIF} except HandleException; end;end;{ ------------------------------------------------------------------------------ }{$IFNDEF USE_WINDOW_MESSAGE}procedure TMsgThread.ClearSendMsgEvent;var aEvent : PHandle;begin EnterCriticalSection( FCtlSect ); try if FEventList.Count <> 0 then begin aEvent := FEventList.Items[ 0 ]; if aEvent <> nil then begin SetEvent( aEvent^ ); CloseHandle( aEvent^ ); Dispose( aEvent ); WaitForSingleObject( fSendMsgComp, INFINITE ); end; FEventList.Delete( 0 ); end; finally LeaveCriticalSection( FCtlSect ); end;end;{$ENDIF}{ ------------------------------------------------------------------------------ }procedure TMsgThread.HandleException;begin FException := Exception( ExceptObject ); // Get Current Exception object try if not( FException is EAbort ) then Synchronize( DoHandleException ); finally FException := nil; end;end;{ ------------------------------------------------------------------------------ }procedure TMsgThread.DoHandleException;begin if FException is Exception then Application.ShowException( FException ) else sysutils.ShowException( FException, nil );end;{ ////////////////////////////////////////////////////////////////////////////// }{$IFDEF USE_WINDOW_MESSAGE}procedure TMsgThread.MSGWinProc( var Message : TMessage );begin DoProcessMsg( message ); if message.Msg < WM_USER then with message do Result := DefWindowProc( FMSGWin, Msg, wParam, lParam );end;{$ENDIF}{ ------------------------------------------------------------------------------ }procedure TMsgThread.DoProcessMsg( var Msg : TMessage );beginend;{ ------------------------------------------------------------------------------ }procedure TMsgThread.ProcessMessage;{$IFNDEF USE_WINDOW_MESSAGE}var uMsg : TMessage;{$ENDIF}begin while PeekMessage( Msg, 0, 0, 0, PM_REMOVE ) do if Msg.Message <> WM_QUIT then begin{$IFDEF USE_WINDOW_MESSAGE} TranslateMessage( Msg ); DispatchMessage( Msg );{$ELSE} uMsg.Msg := Msg.Message; uMsg.wParam := Msg.wParam; uMsg.lParam := Msg.lParam; DoProcessMsg( uMsg );{$ENDIF} end;end;{ ////////////////////////////////////////////////////////////////////////////// }procedure TMsgThread.DoInit;beginend;procedure TMsgThread.DoUnInit;beginend;procedure TMsgThread.DoMsgLoop;begin Sleep( 0 );end;{ ////////////////////////////////////////////////////////////////////////////// }function TMsgThread.ThreadExists : BOOL;begin if m_hThread = 0 then Result := False else Result := True;end;{ ------------------------------------------------------------------------------ }procedure TMsgThread.QuitThread;begin{$IFDEF USE_WINDOW_MESSAGE} PostMessage( FMSGWin, WM_QUIT, 0, 0 );{$ELSE} PostThreadMessage( threadid, WM_QUIT, 0, 0 );{$ENDIF}end;{ ------------------------------------------------------------------------------ }procedure TMsgThread.SetDoLoop( const Value : Boolean );begin if Value = http://www.mamicode.com/fDoLoop then Exit; fDoLoop := Value; if fDoLoop then PostMsg( WM_USER, 0, 0 );end;{ ------------------------------------------------------------------------------ }function TMsgThread.WaitTimeOut( timeout : DWORD ) : Longword;var xStart : Cardinal; H : THandle;begin H := m_hThread; xStart := GetTickCount; while WaitForSingleObject( H, 10 ) = WAIT_TIMEOUT do begin Application.ProcessMessages; if GetTickCount > ( xStart + timeout ) then begin TerminateThread( H, 0 ); Break; end; end; GetExitCodeThread( H, Result );end;{ ------------------------------------------------------------------------------ }function TMsgThread.WaitFor : Longword;var Msg : TMsg; H : THandle;begin H := m_hThread; if GetCurrentThreadID = MainThreadID then while MsgWaitForMultipleObjects( 1, H, False, INFINITE, QS_SENDMESSAGE ) = WAIT_OBJECT_0 + 1 do PeekMessage( Msg, 0, 0, 0, PM_NOREMOVE ) else WaitForSingleObject( H, INFINITE ); GetExitCodeThread( H, Result );end;{ ------------------------------------------------------------------------------ }procedure TMsgThread.PostMsg( Msg : Cardinal; wParam, lParam : Integer );begin{$IFDEF USE_WINDOW_MESSAGE} PostMessage( FMSGWin, Msg, wParam, lParam );{$ELSE} EnterCriticalSection( FCtlSect ); try FEventList.Add( nil ); PostThreadMessage( threadid, Msg, wParam, lParam ); finally LeaveCriticalSection( FCtlSect ); end;{$ENDIF}end;{ ------------------------------------------------------------------------------ }function TMsgThread.SendMsg( Msg : Cardinal; wParam, lParam : Integer ) : Integer;{$IFNDEF USE_WINDOW_MESSAGE}var aEvent : PHandle;{$ENDIF}begin{$IFDEF USE_WINDOW_MESSAGE} Result := SendMessage( FMSGWin, Msg, wParam, lParam );{$ELSE} EnterCriticalSection( FCtlSect ); try New( aEvent ); aEvent^ := CreateEvent( nil, True, False, nil ); FEventList.Add( aEvent ); PostThreadMessage( threadid, Msg, wParam, lParam ); finally LeaveCriticalSection( FCtlSect ); end; WaitForSingleObject( aEvent^, INFINITE ); Result := uMsg.Result; SetEvent( fSendMsgComp );{$ENDIF}end;{ ------------------------------------------------------------------------------ }procedure TMsgThread.Synchronize( syncMethod : TMsgThreadMethod );begin FMethod := syncMethod; SendMessage( SyncWindow, NM_EXECPROC, 0, Longint( Self ) );end;{ ------------------------------------------------------------------------------ }procedure TMsgThread.SyncWindowProc( var Message : TMessage );begin case message.Msg of NM_EXECPROC : with TMsgThread( message.lParam ) do begin message.Result := 0; try FMethod; except raise EMsgThreadErr.Create( ‘执行同步线程方法错误。‘ ); end; end; else message.Result := DefWindowProc( SyncWindow, message.Msg, message.wParam, message.lParam ); end;end;end.
在delphi线程中实现消息循环
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。