Blog. Just Blog

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

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

Тюнинг функции 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.

Читать статью целиком »
Просмотров: 9344 | Комментариев: 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 - установить окно по центру рабочей области, то есть с учетом размеров панели задач и различных тулбаров.

Читать статью целиком »
Просмотров: 8787 | Комментариев: 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
В структуре два типа переменных - пользовательские и служебные. Пользовательские предназначены для задания координат, цвета и других параметров скроллера, они все обязательны для заполнения. Служебные используются процедурой скроллера и не должны изменяться пользователем.

Читать статью целиком »
Просмотров: 8518 | Комментариев: 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-файлу записываются в юникоде, соответственно, все функции работы со строками в вашем приложении должны быть юникодные.

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

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

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

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

01 ... 65 66 67 68 69 70 71 ... 75
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.09 сек. / MySQL: 3 (0.0234 сек.) / Память: 4.5 Mb
Наверх