- ---
make talk easier -> http://dmess.ytu.ru/
DVS> Существуют ли средства и методы для определения активности пользователя
DVS> в системе (а не программе) без внешней библиотеки? Мне не нужен
DVS> какой-нить клавиатурный шпиён и прочее. Ведь многие программы это
DVS> определяют и без DLL: Miranda, WindowsUpTime. Подойдёт вариант и только
DVS> для 2000/XP.
Установка системных WH_KEYBOARD_LL и WH_MOUSE_LL, т.е. хуков низкого
уровня, не требуют библиотеки. Для 2000/XP это, как раз, вполне реализуемо.
Однако, юзер может проявлять активность и другими доступными ему
способами, скажем, шевелить джостиком, засовывать дискеты и т.п. :)
DVS> Так же хотелось бы понять как программы определяют запуск
DVS> "Хранителя экрана".
Система посылает foreground окну WM_SYSCOMMAND c WParam = SC_SCREENSAVE
Т.е., заинтересованному приложению надо устанавливать глобальный
хук WH_GETMESSAGE. Однако, на этот раз, без библиотеки не обойтись ;)
Подробности можно найти в MSDN:
Microsoft Knowledge Base Article - 238882
HOWTO: Know When Your Screen Saver Starts
--
С уважением, LVT.
>skip<
DVS>> Существуют ли средства и методы для определения активности
DVS>> пользователя в системе (а не программе) без внешней библиотеки?
LT> Установка системных WH_KEYBOARD_LL и WH_MOUSE_LL, т.е. хуков низкого
LT> уровня, не требуют библиотеки.
>skip<
жаль только Delphi о них понятия не имеет.
LT> Однако, юзер может проявлять активность и другими доступными ему
LT> способами, скажем, шевелить джостиком, засовывать дискеты и т.п. :)
:) это не существенно. пусть даже фильм смотрит или играет.
LT> Установка системных WH_KEYBOARD_LL и WH_MOUSE_LL, т.е. хуков низкого
LT> уровня, не требуют библиотеки.
DVS> жаль только Delphi о них понятия не имеет.
const
WH_KEYBOARD_LL = 13;
WH_MOUSE_LL = 14;
LLKHF_EXTENDED = KF_EXTENDED shr 8;
LLKHF_INJECTED = $00000010;
LLKHF_ALTDOWN = KF_ALTDOWN shr 8;
LLKHF_UP = KF_UP shr 8;
LLMHF_INJECTED = $00000001;
{ Structure used by WH_KEYBOARD_LL }
type
tagKBDLLHOOKSTRUCT = packed record
vkCode : DWord;
scanCode : DWord;
flags : DWord;
time : DWord;
dwExtraInfo : PDWord;
end;
TKBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;
PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
{ Structure used by WH_MOUSE_LL }
tagMSLLHOOKSTRUCT = packed record
pt : TPoint;
mouseData : DWord;
flags : DWord;
time : DWord;
dwExtraInfo : PDWord;
end;
tMSLLHOOKSTRUCT = tagMSLLHOOKSTRUCT;
PMSLLHOOKSTRUCT = ^TMSLLHOOKSTRUCT;
Вот, например, что когда-то предлагал Джеф Рихтер для
отключения любимых номеров (в вольном переводе):
function LowLevelKeyboardProc(nCode :Longint; awParam: WParam; alParam:
LParam): DWord; stdcall;
var
fEatKeystroke: Boolean;
p: PKBDLLHOOKSTRUCT;
buf: array [0..255] of Char;
sc: UINT;
begin
fEatKeystroke := False;
if (nCode = HC_ACTION) then
case (awParam) of
WM_KEYDOWN, WM_SYSKEYDOWN,
WM_KEYUP, WM_SYSKEYUP:
begin
p := PKBDLLHOOKSTRUCT(alParam);
fEatKeystroke :=
((p.vkCode = VK_TAB) and (p.flags and LLKHF_ALTDOWN <> 0)) or
((p.vkCode = VK_ESCAPE) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or
((p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000)
<>0));
end;
end;
if fEatKeystroke then
Result := 1
else
Result := CallNextHookEx(0, nCode, awParam, alParam);
end;
var
hhk: HHOOK;
procedure TForm1.Button1Click(Sender: TObject);
begin
hhk:= SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, Hinstance, 0);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
UnHookWindowsHookEx(hhk);
end;
--
С уважением, LVT.