Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Восстановление иконки в трее после сбоя системы

02.03.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Если ваше приложение создает и использует свою иконку в трее, то в обязательном порядке надо обрабатывать ситуацию, когда по какой-либо причине произошел сбой и перезапуск Explorer'а. В этом случае перерисовывается панель задач, рабочий стол, системный трей со значками и т.д., и если вы не вернете свою иконку в трей, то она "потеряется". При аварийном перезапуске Explorer'а всем окнам (HWND_BROADCAST) системой отсылается сообщение TaskbarCreated. Особенность этого сообщения в том, что оно не имеет постоянного значения идентификатора, и его значение должно быть получено функцией RegisterWindowMessage. В описаниях этой функции сказано, что она используется для регистрации уникального системного сообщения, но почему-то нигде не указано, что если такое сообщение уже зарегистрировано в системе, то функцией возвращается его существующий идентификатор. Это полезное свойство мы и будем использовать.
  1. ; Сегмент данных
  2. ...
  3. szTBC        db 'TaskbarCreated',0 ; Имя сообщения
  4. restore_msg  dd ?                  ; Идентификатор сообщения TaskbarCreated
  5. ...
Значение идентификатора лучше всего получать на этапе инициализации окна или при запуске приложения, но в любом случае до того, как будет выполняться его обработка.
  1. ; Сегмент кода
  2.         ...
  3.         ; Зарегистрировать сообщение TaskbarCreated
  4.         invoke  RegisterWindowMessage,szTBC
  5.         mov     [restore_msg],eax
  6.         ...
После того, как у вас есть идентификатор сообщения, его можно использовать в обработчике сообщений окна вашего приложения. И, как только оно будет получено, следует просто обновить иконку вашего приложения в трее и выполнить какие-нибудь другие действия по восстановлению работоспособности после перезапуска Explorer'а.
  1.         ...
  2.         ; Сообщение TaskbarCreated?
  3.         mov     eax,[msg]
  4.         cmp     eax,[restore_msg]
  5.         je      .wmrestore
  6.         ...
  7. .wmrestore:
  8.         ; Восстановить иконку в трее
  9.         invoke  Shell_NotifyIcon, NIM_ADD, node
  10.         jmp     .processed
  11.         ...
В этом коде подразумевается, что структура node (NOTIFYICONDATA) была заполнена ранее и содержит всю необходимую информацию об иконке в трее.

Читать статью целиком »
Просмотров: 7566 | Комментариев: 4

Тюнинг функции SHBrowseForFolder

10.02.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Функция API SHBrowseForFolder предназначена для выбора какой-нибудь папки из дерева каталогов всех дисков системы. Со своей задачей она, в принципе, справляется неплохо, но имеет ряд недостатков: окно выбора открывается в произвольных местах экрана, нельзя задать начальный каталог, нельзя менять заголовок окна и т.п. Если посмотреть внимательно на структуру BROWSEINFO, которую функция использует в работе, то в ней обнаруживается интересный параметр - указатель на callback-функцию BrowseCallbackProc. Эта функция получает управление при возникновении различных событий в окне выбора папок. Попробуем с ее помощью немного расширить базовый функционал SHBrowseForFolder. Сперва в сегменте данных определим необходимые значения для создания самого диалога выбора.
  1. ; Описание структуры BROWSEINFO
  2. struct  BROWSEINFO
  3.         hwndOwner            dd ?
  4.         pidlRoot             dd ?
  5.         pszDisplayName       dd ?
  6.         lpszTitle            dd ?
  7.         ulFlags              dd ?
  8.         lpfn                 dd ?
  9.         lParam               dd ?
  10.         iImage               dd ?
  11. ends
  12.  
  13. ; Структура для работы с папками
  14. bi                BROWSEINFO
  15.  
  16. ; Буфер, который получит выбранных путь
  17. szDisplayName     rb MAX_PATH
  18.  
  19. ; Текст подсказки в окне выбора папки
  20. szTitle           db 'Please select folder',0
Вызов функции обычный, за исключением того, что теперь в структуре BROWSEINFO заполнен указатель на callback-функцию:
  1.         ...
  2.         ; Заполнить структуру
  3.         mov     [bi.hwndOwner],NULL
  4.         mov     [bi.ulFlags],BIF_RETURNONLYFSDIRS+BIF_DONTGOBELOWDOMAIN
  5.         mov     [bi.pszDisplayName],szDisplayName
  6.         mov     [bi.lpszTitle],szTitle
  7.         ; Указатель на callback-функцию
  8.         mov     [bi.lpfn],BrowseCallbackProc
  9.  
  10.         ; Открыть диалог выбора папки
  11.         invoke  SHBrowseForFolder,bi
  12.         ...
Флаги диалогового окна, а также значения других параметров структуры BROWSEINFO вы можете посмотреть на сайте MSDN.

Читать статью целиком »
Просмотров: 9339 | Комментариев: 5

Flying Windows 1.6

03.02.2010 | Категория: Мои программы | Автор: ManHunter

Скриншот программы Flying Windows

Эта маленькая программа значительно облегчает работу за компьютером. Написана для личных нужд и включает в себя несколько полезных инструментов:

1. Flying windows
При включенной опции можно перетаскивать при нажатой клавише Alt любое окно за любое место, а не только за заголовок. Очень удобно, когда одновременно открыто много окон или панелей инструментов. В некоторых приложениях дает неожиданный эффект, перетаскивая вместо окна его дочерние элементы. Но это случается крайне редко, мне пока встретилось всего несколько таких программ.

2. Intelligent mousewheel
Эта опция дает возможность прокрутки окон колесиком мышки без установки на них фокуса. Опять же удобно когда открыто много окон.

3. Enabler and unhider
Эта опция позволяет открывать пароли за "звездочками", активировать отключенные кнопки, поля ввода, убирает лимиты количества символов с полей ввода, в качестве побочного эффекта "отвязывает" любые открытые модальные окна. Открытие паролей работает не во всех приложениях. Опция включается через меню или нажатием колесика мыши на иконке в трее. Отключается нажатием колесика мыши на главной иконке в трее или любым нажатием на собственную иконку Enabler'а. Настоятельно не рекомендуется держать Enabler постоянно включенным! Это связано с тем, что создается дополнительная нагрузка на систему и некоторые программы могут работать нестабильно. Также принудительная разблокировка всех подряд элементов во всех окнах может привести, например, к такой ситуации: вы поставите галочку в настройках какой-нибудь программы, а потом окажется что она изначально была заблокирована и взаимосвязана с другой настройкой. К чему это в результате может привести остается только догадываться.

Читать статью целиком »
Просмотров: 45417 | Комментариев: 70

Проверка и обнаружение зависших приложений

27.10.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда для работы требуется определение зависших приложений, окна которых не отвечают на сообщения. Для этого есть два способа. Первый - официально документированный, через функцию SendMessageTimeOut. Особенность ее работы заключается в том, что после отправки сообщения окну она ждет ответ заданное время, и, если ответа от приложения не последовало, то возвращает FALSE. Вот пример использования функции. Нужные константы, как обычно, в FASM не определены, пришлось брать их из других источников.
  1.         ...
  2.         ; Определить таймаут 50 миллисекунд
  3.         TIMEOUT = 50
  4.         ; Определить константу SMTO_ABORTIFHUNG
  5.         SMTO_ABORTIFHUNG = 2
  6.         ; hwnd - хэндл проверяемого окна
  7.         invoke  SendMessageTimeout,[hwnd],NULL,0,0,SMTO_ABORTIFHUNG,TIMEOUT,NULL
  8.         ; Если вернулся 0, то приложение "висит"
  9.         or      eax,eax
  10.         jz      app_hung_up
  11.         ...
Минус использования этой функции в том, что при частой проверке большого количества окон зависших приложений, каждый раз будет отрабатываться таймаут для каждого такого окна, что суммарно может дать снижение производительности вашего приложения. Но повторюсь, Microsoft официально рекомендует к использованию именно эту функцию.

Читать статью целиком »
Просмотров: 8366 | Комментариев: 2

Управление клавишами NumLock, CapsLock и ScrollLock

07.10.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда в программах требуется получать состояние управляющих клавиш или изменять их состояние. Во времена MS-DOS достаточно было просто прочитать или записать значение WORD по определенному адресу памяти, при этом светодиодные индикаторы клавиатуры реагировали на это включением или выключением. Были очень популярны крохотные, в несколько байт, программы для выключения NumLock при загрузке системы, типа таких:
  1. ;-----------------------------------------------------------
  2. ; Программа для выключения индикатора NumLock под MS-DOS
  3. ; Размер .com-файла после компиляции 9 байт
  4. ;-----------------------------------------------------------
  5. .286
  6. .model  tiny
  7. .code                         ; Сегмент кода
  8.         org     100h          ; Зарезервировано для PSP
  9. start:
  10.         pop     ax            ; После запуска в стеке 0, AX=0
  11.         mov     ds,ax         ; DS=0
  12.         mov     ds:[417h],ax  ; WORD DS:[417h] - состояние *Lock'ов
  13.         int     20h           ; Выход из программы
  14. end     start
В свое время это был самый минимальный рабочий код для выключения клавиши NumLock, хоть и не совсем корректный в плане работы со стеком.

Читать статью целиком »
Просмотров: 13319 | Комментариев: 3

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 3 (0.0082 сек.) / Память: 4.5 Mb
Наверх