Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Как определить что комп простаивает?


Автор: Ch0bits 7.8.2007, 11:53
Как определить что компьютер простаивает? Т.е. определенное время не двигается мышь и не нажимаются клавиши?
Если ли стандартные решения или функции API. Как винда это делает когда включает скринсейвер?

Автор: MetalFan 7.8.2007, 12:09
поставить хук на клаву и мышу. при срабатывании запоминать время. по таймеру сравнивать последнее запомненное и текущее.

Автор: Ch0bits 7.8.2007, 12:47
Ставить хуки занятие неблагодарное и чреватое проблемами.
Может быть существуют альтернативные решения?

Автор: Snowy 7.8.2007, 12:56
Код
var
  LastInput:   TLastInputInfo;
begin
  LastInput.cbSize := SizeOf(LastInput);
  if GetLastInputInfo(LastInput) then
    if (GetTickCount - LastInput.dwTime) > 300000 then // 5 минут не видно юзера

Автор: MetalFan 7.8.2007, 13:01
Цитата(Ch0bits @  7.8.2007,  12:47 Найти цитируемый пост)
Ставить хуки занятие неблагодарное и чреватое проблемами.

фига се... а в микрософте то и не знают!
хотя Snowy гораздо более простое решение привел)

Автор: Ch0bits 7.8.2007, 14:47
Но я то знаю правду, что оценка постов это фигня, а настоящий плюс душу греет... Snowy +1  smile 

Цитата(MetalFan @  7.8.2007,  14:01 Найти цитируемый пост)
неоткажусь от (+)

Я сегодня добрый.  smile 

Автор: MetalFan 7.8.2007, 15:13
Цитата(Ch0bits @  7.8.2007,  14:47 Найти цитируемый пост)
Я сегодня добрый.

спасиба конечно)

но про хуки ты зря так ;)

Автор: bems 7.8.2007, 18:34
Цитата(MetalFan @  7.8.2007,  15:13 Найти цитируемый пост)
но про хуки ты зря так ;) 
он прав. а на мелкософте так делают потому что имеют причины делать обоснованные предположения о месте их хука в системной очереди хуков

Автор: MetalFan 7.8.2007, 18:59
Цитата(bems @  7.8.2007,  18:34 Найти цитируемый пост)
он прав.

доказательства?
ниразу не сталкивался с проблемами при использовании хуков)

Автор: Rouse_ 7.8.2007, 21:58
"Комп" - ка существо агрессивное не простаивает никогда - он всегда действует smile
А вот определить, что сейчас приложение не занимается обработкой сообщений, можно по срабатыванию OnIdle...

Автор: DBZ 7.8.2007, 22:15
Заводим Интегер-переменную MsgCount. В WM_CREATE запустить таймер с интервалом скажем 200. Потом в цикле обработки сообщений 

// <- Я имею в виду здесь
case uMsg of
  WM_CREATE:
    begin
      ...
    end;

  WM_ACTIVATEAPP:
    begin
      ...
    end;

  WM_PAINT:
    begin
      ...
    end;

  WM_TIMER:
    begin
      ...
    end;

  ...

  WM_DESTROY:
    begin
      ...
    end;
end;

проставляем: if (uMsg<>WM_TIMER)and(и ещё <> какие-нибудь регулярные мессаги) then MsgCount:=0;

а при каждом срабатывании таймера увеличиваем эту вариаблу на 1.
Если она достигла определённой величины, то резюмируем - юзверь отошёл по делам...
Способ не претендует на замену всем остальным, просто ещё одно соображение в тему.

Автор: Snowy 7.8.2007, 22:29
DBZ, таймер будет работать независимо от того, есть юзер за компом или нет.
Вопрос вообще про определение активности юзера - клава/мыша.
Причём активности в системе, а не приложении.

Автор: MetalFan 7.8.2007, 22:45
мне кажется ответ на вопрос, заданный автором темы, http://forum.vingrad.ru/index.php?showtopic=167187&view=findpost&p=1218980 Snowy  smile

Добавлено через 54 секунды
но мне всетаки хочется услышать весомые аргументы против использования хуков, как таковых....

Автор: Rennigth 8.8.2007, 10:54
Цитата(MetalFan @  7.8.2007,  22:45 Найти цитируемый пост)
но мне всетаки хочется услышать весомые аргументы против использования хуков, как таковых.... 

Лень smile Когда есть более элегантное решение предложеное Showy  smile  smile 

Автор: MetalFan 8.8.2007, 11:03
Цитата(Rennigth @  8.8.2007,  10:54 Найти цитируемый пост)
Когда есть более элегантное решение предложеное Showy

в данном случае да...

но мне интересно, почему
Цитата(Ch0bits @  7.8.2007,  12:47 Найти цитируемый пост)
Ставить хуки занятие неблагодарное и чреватое проблемами.

я так понимаю имелось ввиду использование хуков вообще.
новую тему чтоли завести

Автор: Rennigth 8.8.2007, 11:11
MetalFan, 
Кстати интересно будет smile 

P.S. Я кстати с удовольствием бы послушал бы отзывы людей которые часто используют хуки в своих приложениях. Я их использовал, на клаву вроде и все... ну небыло ситуаций у меня когда без них никак. Хотя сейчас в текущей моей задаче наверное придется ставить на zwTerninateProcess...

P.S.S. Просто интересно на какие грабли ножно наступить, а если наступить, то не очень сильно удариться smile

Добавлено через 12 минут и 10 секунд
Кстати "по моему скромному мнению" было бы не плохо если кто-нибудь, кто шарит хорошо в этом написал бы статейку. Ну чтоб с бегемотами и т.д. smile Будет куда направлять новичков, а то многие начитаются статей ms-rem-а, а с проблемами и не пониманием идут сюда...

Автор: MetalFan 8.8.2007, 11:28
хм) была как-то статейка "Хуки. Аспекты реализации" чтоли называлась) на DelphiWorld точно была,а может счас и в DRKB перенесли

Автор: W4FhLF 8.8.2007, 11:31
MetalFan, что ты так завёлся про хуки? Они отрицательно влияют на быстродействие. Не надо быть гением, чтобы понять это, просто надо представлять себе как это всё работает. 

Сами по себе хуки - это связный список. Вот как описывает схему работы Рихтер:

Цитата


1. Поток процесса В собирается направить сообщение какому-либо окну. 

2. Система проверяет, не установлена ли для данного потока ловушка WH_***. 

3. Затем выясняет, спроецирована ли DLL, содержащая функцию HookProc, на адресное пространство процесса В 

4. Если указанная DLL еще не спроецирована, система отображает ее на адресное пространство процесса В и увеличивает счетчик блокировок (lock count) проекции DLL в процессе В на 1 

5. Система проверяет, не совпадают ли значения hinstDll этой DLL, относящиеся к процессам А и В. Если hinstDll в обоих процессах одинаковы, то и адрес HookProc в этих процессах тоже одинаков. Тогда система может просто вызвать HookProc в адресном пространстве процесса А. Если же hinstDll различны, система определяет адрес функции HookProc в адресном пространстве процесса В по формуле: 

HookProc В = histDll В + (HookProc А - hinstDll А) 

Вычитая hinstDll из HookProc, Вы получаете смещение (в байтах) адреса функции GetMsgProc. Добавляя это смещение к hinstDll В, Вы получаете адрес HookProc, соответствующий проекции DLL в адресном пространстве процесса В 

6. Счетчик блокировок проекции DLL в процессе В увеличивается на 1. 

7. Вызывается HookProc в адресном пространстве процесса В. 

8. После возврата из HookProc счетчик блокировок проекции DLL в адресном пространстве процесса В уменьшается на 1.


Время выполнения 7го этапа напрямую зависит от быстродействия и объёма кода, который содержит твоя HookProc. Потеря быстродействия может быть и незаметна, а может прилично тормозить систему или вообще повешает её. В любом случае, глобальные хуки стоит использовать только при крайней необходимости, когда нет других решений. 

Автор: MetalFan 8.8.2007, 11:51
Цитата(W4FhLF @  8.8.2007,  11:31 Найти цитируемый пост)
Время выполнения 7го этапа напрямую зависит от быстродействия и объёма кода, который содержит твоя HookProc.

в том то и дело, что если грамотно ее написать, то никаких проблем быть НЕ ДОЛЖНО.

Автор: bems 8.8.2007, 15:56
Цитата(MetalFan @  8.8.2007,  11:51 Найти цитируемый пост)
в том то и дело, что если грамотно ее написать, то никаких проблем быть НЕ ДОЛЖНО. 
в том то и дело, что для отсутствия проблем нужно чтобы грамотно были написаны все хуки в системе, а не только твои. Ты никогда не знаешь будет ли у твоегог хука шанс среагировать на событие (не будет ли оно "обработано" более ранним хуком)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)