Blog. Just Blog

Как отследить смену питания на ноутбуке

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Как отследить смену питания на ноутбуке
Как отследить смену питания на ноутбуке

Дополнение к статье о получении информации об оставшемся заряде батареи ноутбука. Запрос состояния батареи по мере надобности - это хорошо, но будет гораздо правильнее, если система сама будет уведомлять наше приложение об изменении типа электропитания, а также об оставшемся заряде аккумулятора. Сегодня я расскажу, как это делается.

Сперва немного GUID'ов, констант и структур. Они понадобятся нам при работе, но FASM "из коробки" про них ничего не знает.
  1. DEVICE_NOTIFY_WINDOW_HANDLE = 0
  2. PBT_POWERSETTINGCHANGE      = 0x8013
  3.  
  4. ; GUID {5D3E9A59-E9D5-4B00-A6BD-FF34FF516548}
  5. GUID_ACDC_POWER_SOURCE \
  6.     dd 05D3E9A59h
  7.     dw 0E9D5h
  8.     dw 04B00h
  9.     db 0A6h, 0BDh, 0FFh, 034h, 0FFh, 051h, 065h, 048h
  10.  
  11. ; GUID {A7AD8041-B45A-4CAE-87A3-EECBB468A9E1}
  12. GUID_BATTERY_PERCENTAGE_REMAINING \
  13.     dd 0A7AD8041h
  14.     dw 0B45Ah
  15.     dw 04CAEh
  16.     db 087h, 0A3h, 0EEh, 0CBh, 0B4h, 068h, 0A9h, 0E1h
  17.  
  18. struct POWERBROADCAST_SETTING
  19.     PowerSetting rb 16
  20.     DataLength   dd ?
  21.     Data         dd ?
  22. ends
Теперь немного теории. Для того, чтобы система могла отправлять вашему приложению уведомления, касающиеся электропитания, оно должно подписаться на них при помощи функции RegisterPowerSettingNotification. В качестве параметров указывается хэндл окна-приемника и GUID требуемого уведомления. При наступлении события система отправляет окну-приемнику сообщение WM_POWERBROADCAST cо значением PBT_POWERSETTINGCHANGE в wParam.
  1.         ; Зарегистрировать уведомление на смену питания
  2.         invoke  RegisterPowerSettingNotification,[hwnddlg],\
  3.                 GUID_ACDC_POWER_SOURCE,\
  4.                 DEVICE_NOTIFY_WINDOW_HANDLE
  5.         mov     [hNotifyPower],eax
  6.  
  7.         ; Зарегистрировать уведомление на изменение заряда батареи
  8.         invoke  RegisterPowerSettingNotification,[hwnddlg],\
  9.                 GUID_BATTERY_PERCENTAGE_REMAINING,\
  10.                 DEVICE_NOTIFY_WINDOW_HANDLE
  11.         mov     [hNotifyBattery],eax
Но это сообщение приходит для всех типов подписанных уведомлений. Чтобы их различать надо анализировать структуру POWERBROADCAST_SETTING, указатель на которую приходит в параметре lParam. Поле PowerSetting этой структуры должно соответствовать нужному значению GUID уведомления, после этой проверки можно уточнить размер данных и, собственно, само значение этих данных. За это отвечают поля DataLength и Data структуры.
  1.         cmp     [msg],WM_POWERBROADCAST
  2.         je      .power
  3.         ...
  4.         ...
  5. .power:
  6.         ; Изменился параметр из числа подписанных?
  7.         cmp     [wparam],PBT_POWERSETTINGCHANGE
  8.         jne     .processed
  9.  
  10.         ; Событие GUID_ACDC_POWER_SOURCE
  11.         push    4
  12.         pop     ecx
  13.         mov     esi,[lparam]
  14.         mov     edi,GUID_ACDC_POWER_SOURCE
  15.         xor     eax,eax
  16.         repe    cmpsd
  17.         jnz     @f
  18.  
  19.         ; Указатель на структуру POWERBROADCAST_SETTING
  20.         mov     eax,[lparam]
  21.         ; [eax+POWERBROADCAST_SETTING.Data] = текущий тип электропитания
  22.         jmp     .processed
  23. @@:
  24.         ; Событие GUID_BATTERY_PERCENTAGE_REMAINING
  25.         push    4
  26.         pop     ecx
  27.         mov     esi,[lparam]
  28.         mov     edi,GUID_BATTERY_PERCENTAGE_REMAINING
  29.         xor     eax,eax
  30.         repe    cmpsd
  31.         jnz     @f
  32.  
  33.         ; Указатель на структуру POWERBROADCAST_SETTING
  34.         mov     eax,[lparam]
  35.         ; [eax+POWERBROADCAST_SETTING.Data] = процент заряда
  36.         jmp     .processed
  37. @@:
Уведомление GUID_ACDC_POWER_SOURCE приходит в обязательном порядке первый раз при подписке на него, а в дальнейшем при изменении типа питания. В поле Data может быть одно из трех возможных значений: 0 - питание от сети, 1 - питание от батареи, 2 - кратковременное питание от UPS или подобных устройств.

Уведомление GUID_BATTERY_PERCENTAGE_REMAINING отправляется системой первый раз после подписки на него, а затем при любом изменении оставшегося заряда батареи. Текущий процент заряда от 0 до 100 передается в параметре Data.

Когда обработка уведомлений больше не требуется, надо отменить подписку с помощью функции UnregisterPowerSettingNotification.
  1.         ; Убрать регистрацию уведомления
  2.         invoke  UnregisterPowerSettingNotification,[hNotifyPower]
  3.         invoke  UnregisterPowerSettingNotification,[hNotifyBattery]
В приложении пример программы с исходным текстом, которая отслеживает изменение питания и изменение процента заряда батареи на ноутбуке.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Power.State.Demo.zip (3,350 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 360 | Комментариев: 0

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0059 сек.) / Память: 4.5 Mb
Наверх