You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
6.0 KiB
Plaintext
219 lines
6.0 KiB
Plaintext
{
|
|
This file is part of R&Q.
|
|
Under same license
|
|
}
|
|
unit hook;
|
|
{$I RnQConfig.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows, Winapi.Messages, System.Classes, System.SysUtils, Vcl.Forms;
|
|
|
|
{$I NoRTTI.inc}
|
|
|
|
procedure InstallMainHook;
|
|
procedure InstallSessionHook;
|
|
procedure UninstallSessionHook;
|
|
function IsMoved(awTime: Integer = -1): Boolean;
|
|
|
|
type
|
|
TMessageHandler = class
|
|
function MainWindowHook(var Message: TMessage): Boolean;
|
|
end;
|
|
|
|
var
|
|
IsHooked: Boolean = False;
|
|
IsLocked: Boolean = False;
|
|
WM_FINDINSTANCE: Integer;
|
|
|
|
function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
|
|
function UnRegisterSessionNotification(Wnd: HWND): Boolean;
|
|
|
|
implementation
|
|
|
|
uses
|
|
GlobalLib, UtilLib, RnQMacros, SciterLib, CLBox;
|
|
|
|
const
|
|
// Only session notifications involving the session attached to by the window
|
|
// identified by the hWnd parameter value are to be received.
|
|
NOTIFY_FOR_THIS_SESSION = 0;
|
|
// All session notifications are to be received.
|
|
NOTIFY_FOR_ALL_SESSIONS = 1;
|
|
|
|
var
|
|
MsgHandler: TMessageHandler;
|
|
FRegisteredSessionNotification: Boolean = False;
|
|
GetLII: function(var plii: TLastInputInfo): BOOL; stdcall;
|
|
|
|
procedure InstallMainHook;
|
|
begin
|
|
Application.HookMainWindow(MsgHandler.MainWindowHook);
|
|
end;
|
|
|
|
procedure InstallSessionHook;
|
|
var
|
|
hndl: THandle;
|
|
begin
|
|
FRegisteredSessionNotification := RegisterSessionNotification(Application.Handle, NOTIFY_FOR_THIS_SESSION);
|
|
if Win32MajorVersion >= 5 then
|
|
begin
|
|
hndl := GetModuleHandle('user32.dll');
|
|
@GetLII := GetProcAddress(hndl, 'GetLastInputInfo');
|
|
if @GetLII = nil then
|
|
Exit;
|
|
IsHooked := True;
|
|
end
|
|
end;
|
|
|
|
procedure UninstallSessionHook;
|
|
begin
|
|
if not IsHooked then
|
|
Exit;
|
|
if FRegisteredSessionNotification then
|
|
UnRegisterSessionNotification(Application.Handle);
|
|
IsHooked := False;
|
|
end;
|
|
|
|
function LastInput: DWORD;
|
|
var
|
|
LInput: TLastInputInfo;
|
|
begin
|
|
LInput.cbSize := SizeOf(TLastInputInfo);
|
|
GetLII(LInput);
|
|
Result := GetTickCount - LInput.dwTime;
|
|
end;
|
|
|
|
function IsMoved(awTime: Integer = -1): Boolean;
|
|
begin
|
|
Result := false;
|
|
if awTime < 0 then
|
|
awTime := autoaway.time;
|
|
if (LastInput + 5 < awTime) then
|
|
Result := True;
|
|
end;
|
|
|
|
function RegisterSessionNotification(Wnd: HWND; dwFlags: DWORD): Boolean;
|
|
// The RegisterSessionNotification function registers the specified window
|
|
// to receive session change notifications.
|
|
// Parameters:
|
|
// hWnd: Handle of the window to receive session change notifications.
|
|
// dwFlags: Specifies which session notifications are to be received:
|
|
// (NOTIFY_FOR_THIS_SESSION, NOTIFY_FOR_ALL_SESSIONS)
|
|
type
|
|
TWTSRegisterSessionNotification = function(Wnd: HWND; dwFlags: DWORD): BOOL; stdcall;
|
|
var
|
|
hWTSapi32dll: THandle;
|
|
WTSRegisterSessionNotification: TWTSRegisterSessionNotification;
|
|
begin
|
|
Result := false;
|
|
hWTSapi32dll := LoadLibrary('Wtsapi32.dll');
|
|
if (hWTSapi32dll > 0) then
|
|
begin
|
|
try
|
|
@WTSRegisterSessionNotification := GetProcAddress(hWTSapi32dll, 'WTSRegisterSessionNotification');
|
|
if Assigned(WTSRegisterSessionNotification) then
|
|
Result := WTSRegisterSessionNotification(Wnd, dwFlags);
|
|
finally
|
|
if hWTSapi32dll > 0 then
|
|
FreeLibrary(hWTSapi32dll);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function UnRegisterSessionNotification(Wnd: HWND): Boolean;
|
|
type
|
|
TWTSUnRegisterSessionNotification = function(Wnd: HWND): BOOL; stdcall;
|
|
var
|
|
hWTSapi32dll: THandle;
|
|
WTSUnRegisterSessionNotification: TWTSUnRegisterSessionNotification;
|
|
begin
|
|
Result := false;
|
|
hWTSapi32dll := LoadLibrary('Wtsapi32.dll');
|
|
if (hWTSapi32dll > 0) then
|
|
begin
|
|
try
|
|
@WTSUnRegisterSessionNotification := GetProcAddress(hWTSapi32dll, 'WTSUnRegisterSessionNotification');
|
|
if Assigned(WTSUnRegisterSessionNotification) then
|
|
Result := WTSUnRegisterSessionNotification(Wnd);
|
|
finally
|
|
if hWTSapi32dll > 0 then
|
|
FreeLibrary(hWTSapi32dll);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TMessageHandler.MainWindowHook(var Message: TMessage): Boolean;
|
|
var
|
|
Len: Integer;
|
|
Data: String;
|
|
Size: TFormPos;
|
|
begin
|
|
Result := False;
|
|
if Message.Msg = WM_FINDINSTANCE then
|
|
begin
|
|
Message.Result := 1337;
|
|
Result := True;
|
|
end else
|
|
case Message.Msg of
|
|
WM_HANDLEICQLINK:
|
|
begin
|
|
SetLength(Data, MAX_PATH);
|
|
Len := GlobalGetAtomName(Message.WParam, PChar(Data), MAX_PATH);
|
|
GlobalDeleteAtom(Message.WParam);
|
|
SetLength(Data, Len);
|
|
ProcessICQLink(Data);
|
|
Result := True;
|
|
end;
|
|
WM_HOTKEY:
|
|
begin
|
|
if HotkeysEnabled and not Locked then
|
|
ExecuteMacro(Macros[Message.WParam].opcode);
|
|
Result := True;
|
|
end;
|
|
WM_WTSSESSION_CHANGE:
|
|
case Message.WParam of
|
|
WTS_CONSOLE_CONNECT: IsLocked := False;
|
|
WTS_CONSOLE_DISCONNECT: IsLocked := True;
|
|
WTS_REMOTE_CONNECT: IsLocked := False;
|
|
WTS_REMOTE_DISCONNECT: IsLocked := True;
|
|
WTS_SESSION_LOGON: IsLocked := False;
|
|
WTS_SESSION_LOGOFF: IsLocked := True;
|
|
WTS_SESSION_LOCK: IsLocked := True;
|
|
WTS_SESSION_UNLOCK: IsLocked := False;
|
|
end;
|
|
WM_DISPLAYCHANGE:
|
|
begin
|
|
Len := GetActiveMonitorCount;
|
|
if not (LastMonCnt = Len) then
|
|
begin
|
|
LastMonCnt := Len;
|
|
if CLBox.MonPositions.TryGetValue(LastMonCnt, Size) then
|
|
begin
|
|
TThread.CreateAnonymousThread(procedure
|
|
begin
|
|
Sleep(1000);
|
|
TThread.Synchronize(nil, procedure
|
|
begin
|
|
if Assigned(UI) and Assigned(UI.CL) then
|
|
UI.CL.SetPosition(Size.Left, Size.Top);
|
|
end);
|
|
end).Start;
|
|
end;
|
|
end;
|
|
end;
|
|
WM_EXITSIZEMOVE:
|
|
UI.CL.SavePositionForCurrentMonitorCount;
|
|
end;
|
|
end;
|
|
|
|
initialization
|
|
WM_FINDINSTANCE := RegisterWindowMessage('Unique R&Q message');
|
|
MsgHandler := TMessageHandler.Create;
|
|
|
|
finalization
|
|
MsgHandler.Free;
|
|
|
|
end.
|