Blog. Just Blog

Образ мышления: Assembler

То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал Образ мышления: Assembler - Карта сайта

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

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) была заполнена ранее и содержит всю необходимую информацию об иконке в трее.

Читать статью целиком »
Просмотров: 6712 | Комментариев: 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.

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

Установка окна по центру экрана

05.01.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Для того, чтобы создаваемое диалоговое окно отображалось в самом центре экрана, его надо создать с атрибутом стиля DS_CENTER. Но иногда требуется отцентровать уже созданное или чужое окно. Для этого я написал небольшую функцию, устанавливающую выбранное окно по центру экрана, с некоторыми дополнительными возможностями. Функция самодостаточна, не требует дополнительных переменных в сегменте данных, корректно работает с любыми окнами, пропуская развернутые на весь экран.
  1. ;-------------------------------------------------------------------------
  2. ; Процедура перемещения окна в центр экрана. Если окно развернуто или
  3. ; его размеры превышают размеры экрана, то окно не перемещается
  4. ; Параметры:
  5. ;   hwnd - хэндл окна
  6. ;   mode - относительно каких координат центровать окно (1 - только
  7. ;          рабочая область экрана с учетом размеров панели задач и
  8. ;          различных тулбаров, 0 - относительно размеров всего экрана)
  9. ;-------------------------------------------------------------------------
  10. proc    WindowToCenter hwnd:DWORD, mode:DWORD
  11.         ; Локальные переменные, они же структура RECT
  12.         local   left   :DWORD
  13.         local   top    :DWORD
  14.         local   right  :DWORD
  15.         local   bottom :DWORD
  16.  
  17.         ; Сохранить все регистры
  18.         pusha
  19.  
  20.         ; Такое окно существует?
  21.         invoke  IsWindow,[hwnd]
  22.         or      eax,eax
  23.         jz      .loc_ret
  24.         ; Окно развернуто на весь экран?
  25.         invoke  IsZoomed,[hwnd]
  26.         or      eax,eax
  27.         jnz     .loc_ret
  28.  
  29.         ; Получить размеры окна
  30.         lea     eax,[left]
  31.         invoke  GetWindowRect,[hwnd],eax
  32.  
  33.         ; Флаги функции SetWindowPos
  34.         push    SWP_NOSIZE+SWP_NOZORDER
  35.         push    NULL
  36.         push    NULL
  37.  
  38.         ; Какие размеры экрана получать
  39.         mov     eax,SM_CYSCREEN      ; Вся экранная область
  40.         cmp     [mode],0
  41.         je      @f
  42.         mov     eax,SM_CYFULLSCREEN  ; Рабочая область экрана
  43. @@:
  44.         ; Получить высоту экрана
  45.         invoke  GetSystemMetrics,eax
  46.         mov     ecx,[bottom]
  47.         sub     ecx,[top]
  48.  
  49.         ; Высота окна больше высоты экрана?
  50.         cmp     ecx,eax
  51.         jbe     @f
  52.  
  53.         ; Почистить стек и на выход
  54.         add     esp,12
  55.         jmp     .loc_ret
  56. @@:
  57.         sub     eax,ecx
  58.         shr     eax,1
  59.         ; Новая координата Y
  60.         push    eax
  61.  
  62.         ; Какие размеры экрана получать
  63.         mov     eax,SM_CXSCREEN      ; Вся экранная область
  64.         cmp     [mode],0
  65.         je      @f
  66.         mov     eax,SM_CXFULLSCREEN  ; Рабочая область экрана
  67. @@:
  68.         ; Получить ширину экрана
  69.         invoke  GetSystemMetrics,eax
  70.         mov     ecx,[right]
  71.         sub     ecx,[left]
  72.  
  73.         ; Ширина окна больше ширины экрана?
  74.         cmp     ecx,eax
  75.         jbe     @f
  76.  
  77.         ; Почистить стек и на выход
  78.         add     esp,16
  79.         jmp     .loc_ret
  80. @@:
  81.         sub     eax,ecx
  82.         shr     eax,1
  83.         ; Новая координата X
  84.         push    eax
  85.  
  86.         ; Разместить окно по центру экрана
  87.         invoke  SetWindowPos,[hwnd],NULL
  88.  
  89. .loc_ret:
  90.         ; Восстановить все регистры
  91.         popa
  92.         ret
  93. endp
Параметры вызова: hwnd - хэндл окна, которое надо отцентровать, mode - режим центровки: 0 - установить окно по центру всего экрана, 1 - установить окно по центру рабочей области, то есть с учетом размеров панели задач и различных тулбаров.

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

Эффект бегущей строки на Ассемблере

14.12.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Очередной интересный визуальный эффект для ваших программ - бегущая строка. Обычно подобный эффект используется в различных кейгенах, но вполне может пригодиться и для более мирных приложений. В качестве основы взята ассемблерная библиотека Scroller lib 1.01 от ReWolf / HTBTeam. Изначально она предназначалась для MASM, так что пришлось ее портировать под FASM. В процессе переноса библиотека была немного переработана и дополнена, а также упрощена ее структура и подключение к проектам. Сперва в сегменте данных определяются вспомогательные константы и структура для создания скроллера.
  1. ; Константы, определяющие режим скроллера
  2. SCROLL_START = 0  ; Скроллер запущен
  3. SCROLL_PAUSE = 1  ; Скроллер на паузе
  4. SCROLL_STOP  = 2  ; Скроллер полностью остановлен
  5.  
  6. ; Структура для скроллера
  7. struct SCROLLSTRUCT
  8.         ; Значения заполняются пользователем
  9.         hwDlg      dd ?  ; Хэндл окна для скроллера
  10.         hFont      dd ?  ; Шрифт скроллера
  11.         ddWidth    dd ?  ; Ширина скроллера
  12.         X          dd ?  ; Координата X
  13.         Y          dd ?  ; Координата Y
  14.         lpstrText  dd ?  ; Строка скроллера ASCIIZ
  15.         ddTxtColor dd ?  ; Цвет текста скроллера
  16.         ddBkgColor dd ?  ; Цвет фона скроллера
  17.         ddSpeed    dd ?  ; Скорость движения
  18.         dbMode     db ?  ; Режим скроллера
  19.  
  20.         ; Внутренние переменные
  21.         ddROP      dd ?
  22.         hBkgDC     dd ?
  23.         hTxtBmp    dd ?
  24.         hTmpBmp    dd ?
  25.         hBakTmpBmp dd ?
  26.         hInDC      dd ?
  27.         ddHeight   dd ?
  28.         ddPos      dd ?
  29.         ddTxtWidth dd ?
  30. ends
В структуре два типа переменных - пользовательские и служебные. Пользовательские предназначены для задания координат, цвета и других параметров скроллера, они все обязательны для заполнения. Служебные используются процедурой скроллера и не должны изменяться пользователем.

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

Диалоговые окна из html-файлов на Ассемблере

29.11.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Использование html-файлов для создания диалоговых окон применяется чаще всего в качестве сплэш-скринов разных триальных защит (первое, что приходит на память - протектор Armadillo и wrapper'ы от различных игровых дистрибьюторов) или в некоторых "демонстрашках", использующих графические эффекты. Плюсов тут много: вместо кропотливой низкоуровневой обработки шрифтов и цветных символов, визуальных эффектов и картинок, достаточно все это описать обычным CSS и HTML-тегами в HTML-странице, а с помощью скриптов JavaScript добавить нужную интерактивность. Кроме этого можно вынести из основного программного кода часть каких-нибудь зубодробильных вычислений на JavaScript, а потом передать результат основному приложению. У меня, например, по такому принципу написана новая версия Eval JavaScript Unpacker.

Для создания окна сперва надо определить в сегменте данных некоторые значения. Главные из них - имя HTML-файла и параметры открываемого окна.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. szRes     du      'res://',0
  5. lenRes    = $-szRes-2
  6. szName    du      '/htmldialog.html',0 ; Имя html-файла в ресурсах
  7.  
  8. szParam   du      'dialogWidth:350px;dialogHeight:200px;help:off;',0
  9. hMoniker  dd      ?       ; Хэндл моникера
  10. szUrl     rb      200h    ; Путь к основному файлу
szParam - размер и дополнительные параметры создаваемого диалогового окна, их полный список и доступные значения есть в описании функции showModalDialog. Обратите внимание, что строки пути к HTML-файлу записываются в юникоде, соответственно, все функции работы со строками в вашем приложении должны быть юникодные.

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

prev 01 ... 35 36 37 38 39 40 41 ... 45 next
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2021
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.11 сек. / MySQL: 2 (0.0038 сек.) / Память: 4.75 Mb
Наверх