unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, SvcMgr;
const
WM_MyMessage = WM_USER + 100;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
TMsgThread = class(TThread)
private
Atom1: atom;
FMyString: string;
procedure ShowString;
public
constructor Create(CreateSuspended: Boolean); overload;
destructor Destroy; override;
procedure ProcessRequests(WaitForMessage: Boolean);
protected
procedure Execute; override;
end;
//http://topic.csdn.net/t/20030218/17/1440830.html 在线程中怎样处理消息
//can zhao SvcMgr.pas zhong de TServiceThread
//另类远程线程插入法 http://www.blogcn.com/user17/fmtwld/blog/4441223.html
TMsgThread2 = class(TThread)
private
atomF4: atom;
CanTerminated: Boolean;
FMyString: string;
procedure ShowString;
procedure NotificationWndProc(var Message: TMessage);
public
MHandle: HWnd;
constructor Create(CreateSuspended: Boolean); overload;
destructor Destroy; override;
protected
procedure Execute; override;
end;
var
Form1: TForm1;
TestThread: TMsgThread;
TestThread2: TMsgThread2;
implementation
{$R *.dfm}
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
PostMessage(TestThread2.MHandle, WM_CLOSE, 0, 0);
sleep(300);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if assigned(TestThread) then
PostThreadMessage(TestThread.ThreadID, WM_QUIT, 0, 0);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if assigned(TestThread) then
PostThreadMessage(TestThread.ThreadID, WM_MyMessage, 0, 0);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if assigned(TestThread2) then
PostMessage(TestThread2.MHandle, WM_CLOSE, 0, 0);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TestThread := TMsgThread.Create(False);
TestThread2 := TMsgThread2.Create(False);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if assigned(TestThread) then
begin
TestThread.Terminate;
if TestThread.Suspended then
TestThread.Suspend;
TestThread.WaitFor;
FreeAndNil(TestThread);
end;
if assigned(TestThread2) then
begin
TestThread2.Terminate;
if TestThread2.Suspended then
TestThread2.Suspend;
TestThread2.WaitFor;
FreeAndNil(TestThread2);
end;
end;
{ TMsgThread }
constructor TMsgThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
end;
destructor TMsgThread.Destroy;
begin
inherited;
end;
procedure TMsgThread.Execute;
var
msg: TMsg;
begin
Atom1:=globalfindatom('HotKeyIDhzh');
if Atom1=0 then
Atom1 := GlobalAddAtom('HotKeyIDhzh');
RegisterHotKey(0, Atom1, MOD_CONTROL, ord('B'));
//RegisterHotKey(Handle, atomF4, 0, vk_F4);
FMyString := 'Thread Started!';
Synchronize(ShowString);
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE); { Create message queue }
//ProcessRequests(True);
ProcessRequests(False);
UnRegisterHotKey(0, Atom1); //取消热键
GlobalDeleteAtom(Atom1);
end;
{procedure TMsgThread.Execute;
var
Msg: TMsg;
DMsg: TMessage;
begin
FMyString := 'Thread Started!';
Synchronize(ShowString);
while (not Terminated) do
begin
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
if (Msg.message = WM_QUIT) then
begin
FMyString := 'Thread QuIT';
Synchronize(ShowString);
Terminate;
end;
if (Msg.message = WM_MyMessage) then
begin
FMyString := 'Thread Get a USER Message!';
Synchronize(ShowString);
end;
if (Msg.message = WM_HOTKEY) then
begin
DMsg.Msg := Msg.message;
DMsg.wParam := Msg.wParam;
DMsg.lParam := Msg.lParam;
DMsg.Result := 0;
//if (DMsg.LParamLo = MOD_CONTROL) and (DMsg.LParamHi = ord('B')) then
begin
FMyString := 'TMsgThread Get Ctrl R!';
Synchronize(ShowString);
end;
end;
end;
end;
end;}
procedure TMsgThread.ProcessRequests(WaitForMessage: Boolean);
var
msg: TMsg;
DMsg: TMessage;
Rslt: Boolean;
begin
while not Terminated do
begin
//FillChar(msg, sizeof(msg), #0);
if WaitForMessage then
Rslt := GetMessage(msg, 0, 0, 0)
else
Rslt := PeekMessage(msg, 0, 0, 0, PM_REMOVE);
if not Rslt then // Some Meesage will PM_REMOVE Fail
begin
//FMyString := 'PeekMessage none!';
//Synchronize(ShowString);
//break;
continue;
end;
if Rslt and (msg.hwnd = 0) then { Thread message }
begin
if (Msg.message = WM_QUIT) then
begin
FMyString := 'Thread QuIT';
Synchronize(ShowString);
Terminate;
end
else
if (Msg.message = WM_MyMessage) then
begin
FMyString := 'Thread Get a USER Message!';
Synchronize(ShowString);
end
else
if (Msg.message = WM_HOTKEY) then
begin
DMsg.Msg := Msg.message;
DMsg.wParam := Msg.wParam;
DMsg.lParam := Msg.lParam;
DMsg.Result := 0;
if (DMsg.LParamLo = MOD_CONTROL) and (DMsg.LParamHi = ord('B')) then
begin
FMyString := 'TMsgThread Get Ctrl B!';
Synchronize(ShowString);
end;
end
else
DispatchMessage(msg);
end else
DispatchMessage(msg);
end;
end;
procedure TMsgThread.ShowString;
begin
Form1.Memo1.Lines.Add(FMyString);
end;
{ TMsgThread2 }
constructor TMsgThread2.Create(CreateSuspended: Boolean);
begin
CanTerminated := False;
MHandle := Classes.AllocateHWnd(NotificationWndProc);
atomF4 := GlobalAddAtom('hot_key2');
//RegisterHotKey(Mhandle, atomF4, 0, vk_F4);
RegisterHotKey(Mhandle, atomF4, MOD_CONTROL, ord('R'));
inherited Create(CreateSuspended);
end;
destructor TMsgThread2.Destroy;
begin
UnRegisterHotKey(Mhandle, atomF4); //取消热键
GlobalDeleteAtom(atomF4); //释放id
if MHandle <> 0 then
Classes.DeallocateHWnd(MHandle);
inherited;
end;
procedure TMsgThread2.Execute;
begin
while (not CanTerminated) do
begin
Sleep(300);
end;
end;
procedure TMsgThread2.NotificationWndProc(var Message: TMessage);
begin
if Message.Msg = WM_CLOSE then
begin
CanTerminated := True;
if CanTerminated then
begin
FMyString := 'Thread2 QuIT';
Synchronize(ShowString);
end;
end;
if Message.Msg = WM_HOTKEY then
if (Message.LParamLo = MOD_CONTROL) and (Message.LParamHi = 82) then
begin
FMyString := 'TMsgThread2 Get Ctrl R!';
Synchronize(ShowString);
end;
end;
procedure TMsgThread2.ShowString;
begin
if assigned(Form1) and assigned(Form1.Memo1) then
Form1.Memo1.Lines.Add(FMyString);
end;
end.
https://www.cnblogs.com/marklove/p/12340681.html
来源:oschina
链接:https://my.oschina.net/u/4373225/blog/4263347