Inactivity detection

46 отговора 890 прегледа
#1

Inactivity detection

Hi, тази тема май е засягана (в различна степен) неколкократно, но на когото не му е досадно, нека даде акъл.
Целта е да се отчита бездействието на потребителя без използване на Hooks и без да се разчита на ScreenSaver-а.
Степента на достоверност може да не е непременно 100%, а някъде към 90 :-))
Днес си направих експеримент да свърша работата със следене за смяна на активното приложение, активния контрол в него и позицията на курсора, но в случая с конзолните приложения претърпях крах :-\\ (За съжаление имам сумати юзъри, ползващи интензивно промпта...)

Отговор
в отговор на bass #2

Re: Inactivity detection

kwo ti prechat HOOKS? po krasivo ot s hooks nema kak da stane ....

------------------------------
I got a COMPILER, and I'm not afraid to use it!
Отговор
в отговор на SDR #3

Re: Inactivity detection

>> kwo ti prechat HOOKS?

Windows SDK:
"Hooks tend to slow down the system because they increase the amount of processing the system must perform for each message. You should install a hook only when necessary, and remove it as soon as possible. "

Да е за нещо сериозно - разбирам, а тва мойто е едно пикливо приложенийце, което на всичкото отгоре виси през цялото време в SystemTray.
Помня, че в предни теми имаше един пост "В крайна сметка бавни ли са Hooks?", но нещо не мога да го изровя.

Редактирано от bass на

Отговор
в отговор на bass #4

Re: Inactivity detection

Няма да минеш без тях колкото и да ти е тъжно ;-)))) - всяко нещо си има цена - за да следиш какво правят мишката и клавиатурата - друг начин няма - освен начина по който се извиква screen saver-a може би. Лошото е че това май е системно събитие и няма как да се закачаш по-поразличен начин т.е. да не се пуска ssaver-a ами да ти праща съобщение на твоята програма.
Всъщност темата май си я гледал някъде другаде(не в този клуб) - и реално бързината зависи от това как точно ти е написана callback функцията и какво прави тя. Вярно забавяне за изпъление има - но ако функцията ти гълта повече време за изпълнение от колкото за самото извикване (от системата) - си е твой проблем - тука бих ти препоръчал ако гониш бързодействие да си я напишеш на нещо друго (разбирай VC ) а не Delphi.

---
Е т'ва е живот!
Отговор
в отговор на PhantomAS #5

Re: Inactivity detection

Доколкото си спомням, преди да тръгне ScreenSaver-a се праща съобщение до всички активни процеси (или прозорци само, не помня) и ако всички го пуснат той си се задейства. Затова напр. докато си гледате Matrix: Revolutions, филма си бичи 2 часа и кусур и никви сейвъри или други тъпотии не ви смущават - просто плеъра не дава на сейвъра да тръгне.

Mixy
Отговор
в отговор на Mixy #6

Re: Inactivity detection

>>освен начина по който се извиква screen saver-a може би
Рових доста из MSDN-а и въобще в нета да разбера как точно сработва ScreenSavera (дали като просто приложение с Hook или по-хитро някак си)... ама без успех :-((


>>преди да тръгне ScreenSaver-a се праща съобщение до всички активни процеси (или прозорци само, не помня) и ако всички го пуснат той си се задейства.
Съобщение се праща при смяна на системните настройки (в частност - на на ScreeSaver-а), но не и при активиране/деактивиране (или поне аз не можах да изровя такова суперудобно нещо). В началото наивно помислих, че SPI_SETSCREENSAVEACTIVE е мойто събитие :-\\
А иначе целевото изключване на ScreenSaver-а не е проблем, но това е друга тема.
btw, преди 2000/XP даже няма API за проверка дали в момента е активен ScreenSavera-а или не...

Отговор
в отговор на bass #7

Re: Inactivity detection

Относно детект на неактивност - почти съм 99% сигурен вече, че може да се заобиколи hook- а(или поне да не е в явен dll) , една руска фирма беше пуснала компонент който го правеше (обаче не съм сигурен дали просто това което правят не е на по ниско ниво ??). Обаче не можах да го намеря в нета - май го имам някъде по дисковете - ама преди другата седмица нямам време да ровя.
Също подобен компонент (хвалят се, че го правят също без hook) и една друга фирма - правеща AppControls. Потърси ги - и дръпни демото - да видиш какви API функции ползват - това поне лесно можеш да направиш.
Имам обаче лошото чувство, че май го правят (пак чрез кука) - но без dll -явно това е хватката - ако това ти върши работа - мога да ти пратя код.

---
Е т'ва е живот!
Отговор
в отговор на bass #8

Re: Inactivity detection

оппа...полека полека с хууковете....

И да ! Преди да тръгне скрийнсейвъра Виндовса броудкаства WM_SYSCOMMAND message със wParam = SC_SCREENSAVER, така че ако си пуснеш приложението и го хванеш това съобщение и върнеш ТРУ скрийнсйвъра нема да тръгне и ти ще си делкаш там каквото си ти трябва....

There are 10 types of people in this world one who understand binary jokes and one who not
Отговор
в отговор на synchu #9

Re: Inactivity detection

Аха, сега ще го изтествам тва, 10x.
Иначе скрийнсейвъра не ми пречи - нека си се пуска. Не ми се искаше обаче да разчитам на него, понеже може някой юзър да реши да го спре :-))

Отговор
в отговор на PhantomAS #10

10x,

Ще имам материал за уикенда :-)
btw, като споменах за работа през уикенда, в този клуб забелязвам много похвално явление - след 20.00 почти няма народ тук, което говори за отлична трудова дисциплина (за разлика от "Системни администратори", например) :-P

Отговор
в отговор на bass #11

Re: Inactivity detection

велком ;)

неведоми са пътищата юзерски ...;)

но за съжаление има само още два варианта:
- хуукс който е стандартния и беше предложен по-горе;
- МСДДК (драйвер дивелопмънт кита) - с който директно си играеш с прекъсванията на съответния дивайс - т.е. клавиатурата и мишката ;) Това е най-сигурния, най-бърз и съответно най-трудния за реализация вариант.

Т.е. ако не е за нещо критично най-добре да е да е по КИС схемата (кийп ит симпъл);)

There are 10 types of people in this world one who understand binary jokes and one who not
Отговор
в отговор на synchu #12

Re: Inactivity detection

>>най-добре да е да е по КИС схемата (кийп ит симпъл)
Тва се намира някъде в първата тройка на личния ми списък с принципи :-))
btw, подходът със WM_SYSCOMMAND/SC_SCREENSAVE може да спечели по точки (върви много гладко и неангажиращо и си струва компромиса в моя случай), но решава само едната половина на проблема. Другата се състои в това да разбера кога се деактивира SS-a :-\\
Отивам да чета по въпроса...

Отговор
в отговор на bass #13

Re: Inactivity detection

деактивира се при същия месидж WM_SYSCOMMAND и WPARAM e SC_CLOSE ...или нещо подобно ама го провери пак...

There are 10 types of people in this world one who understand binary jokes and one who not
Отговор
в отговор на bass #14

Има само един недостатък...

Че разчиташ на времето заложено за screensaver-a а не на твое собствено и какво ще стане ако някой пипне времето или просто го забрани ;-))))).
А бе защо никой не се сети да порови из фунцкиите за advanced power mangement - там не може да няма подобни функции!!! Как примерно загасят и монитора след определно време или sleep режима - няма как да не са реализирани подобни функции които да връщат време от последното действие (то може да не е само от потребителя? )?
Лошото е, че ако го има - сигурно ще е смислено дефинирано само за версиите на win след МЕ.

---
Е т'ва е живот!

Редактирано от PhantomAS на

Отговор
в отговор на synchu #15

Re: Inactivity detection

>>деактивира се при същия месидж WM_SYSCOMMAND и...
На първо четене не щя - пробвах така да видя дали ще прихване нещо, ама Ц...


...
private
procedure OnSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;

...

procedure TForm1.OnSysCommand(var Message: TWMSysCommand);
begin
if Message.CmdType = SC_SCREENACTIVE then Memo1.Lines.Add('Activated') //ОК
else Memo1.Lines.Add('Deactivated by ' + IntToStr(Message.CmdType)); //При спиране на SS-a не се случва нищо
end;


Отговор
в отговор на bass #16

Re: Inactivity detection

мдам....шит хепънс....;)
значи съм го позабравил...
емдругия вариант, за да видиш, кой точно е месиджа е да цапнеш един хуук и със същия код да видиш кой е месиджа, който пуска надолу е примерен код в еретичен "Ц" вид ;) сорри нямам Делфи наоколо

при старта на приложението:

UINT hHook;
hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)HookProc,
NULL, 0);

и отдолу хукпроца:

LRESULT CALLBACK HookProc(UINT code , WPARAM wParam, LPARAM lParam)
{
MSG *msg = (MSG *)lParam;
if ( msg->message == WM_SYSCOMMAND &&
msg->wParam == SC_SCREENSAVE)
{
//пускаш един флаг тука че е пуснат скринсейвъра
//
}
if <flaga e pusnat> { puskash msgite kym tvoja si kontrol}

return CallNextHookEx(hHook, code, wParam, lParam);
}

и като излизаш пускаш задължително (че иначе пръчка ;)) )
UnhookWindowsHookEx( hHook );

е тука таме може да се сложи някоя проверка дали хХуук е != НУЛ и т.н...

There are 10 types of people in this world one who understand binary jokes and one who not
Отговор
в отговор на synchu #17

Re: Inactivity detection

Ми става, то по време на бездействие на юзъра очевидно не му пука колко му е бърз компа (има ли хук или няма) :-))
btw, за мен "C" хич не е еретичен, че с него съм почнал - с Делфи работя от има-няма 2 години. Даже в началото успях да възмутя някой от модераторите във форума :-P

Отговор
в отговор на bass #18

Deeper look on the problem

RegisterHotKey <-registrirash si Enter Space Shifta, Strelkite ;) za mishkata - periodichno prowerqwash poziciqta - ako ne se e promenila weroqtno ne e dwijena w promejdutaka - i si gotof :) are pak sha cherpish drug pat

------------------------------
I got a COMPILER, and I'm not afraid to use it!
Отговор
в отговор на SDR #19

Re: Deeper look on the problem

The RegisterHotKey function defines a hot key for the current thread
Тва не значи ли, че горещите клавищи са дефинирани в рамките на текущото приложение?
А ако не значи и съм разбрал правилно, предлагаш целия инпут на системата (добре де, не целия, ма много съществена част от него) да мине през мойто, както вече го дефинирах, пикливо приложенийце ;-) ?

Отговор
в отговор на synchu #20

Тесла!

Оказа се, че приложенията, минимизирани в таскбара, както и иконите в SystemTray (моя случай) нещо не получават WM_SYSCOMMAND с SC_SCREENSAVE...

Отговор