Blog. Just Blog

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

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

Управление клавишами 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, хоть и не совсем корректный в плане работы со стеком.

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

Подсказки (tooltips) в диалоговых окнах

16.09.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Еще один способ придать вашим программам профессиональный вид - использование всплывающих подсказок (tooltips), которые появляются при наведении курсора мыши на какой-нибудь элемент диалогового окна. Готовые примеры на FASM или слишком громоздкие, или недостаточно гибкие, поэтому пришлось придумывать что-то свое. Причем с самого начала поставил себе задачу сделать функции работы с подсказками как можно более универсальными, чтобы в дальнейшем их можно было легко использовать в других проектах.

В сегменте данных определим все необходимые константы, переменные и структуры. Большая часть этих данных в FASM по умолчанию отсутствует, так что пришлось штудировать MSDN и другие источники и описывать их самостоятельно.
  1. ; Сегмент данных
  2. section '.data' data readable writeable  
  3.  
  4. hwndTip         dd ?    ; Хэндл окна подсказки
  5. TTipFlag        dd ?    ; Флаг активности подсказки
  6.  
  7. ; Структура TRACKMOUSEEVENT не определена, сделаем это сами
  8. struct TRACKMOUSEEVENT
  9.   cbSize        dd ?
  10.   dwFlags       dd ?
  11.   hwndTrack     dd ?
  12.   dwHoverTime   dd ?
  13. ends
  14.  
  15. ; Определяем нужные структуры
  16. tme     TRACKMOUSEEVENT
  17. pt      POINT
  18. ttip    TOOLINFO
  19. trect   RECT
  20.  
  21. oldX    dd ?    ; Сохраненные координаты мыши
  22. oldY    dd ?
  23.  
  24. ; Определяем нужные константы
  25. TTM_TRACKACTIVATE  = WM_USER + 17
  26. TTM_TRACKPOSITION  = WM_USER + 18
  27. TTM_SETMAXTIPWIDTH = WM_USER + 24
  28.  
  29. ; Сообщения окну подсказки
  30. TTF_SUBCLASS       = 0x0010
  31. TTF_TRACK          = 0x0020
  32. TTF_ABSOLUTE       = 0x0080
  33. TTF_TRANSPARENT    = 0x0100
  34.  
  35. ; Сообщение обработчика мыши
  36. TME_LEAVE          = 0x00000002
  37.  
  38. ; Максимальная ширина всплывающей подсказки
  39. TOOLTIP_WIDTH      = 200
  40.  
  41. ; Предустановленное количество элементов в массиве подсказок
  42. TOOLTIPS_COUNT     = 5
  43.  
  44. ; Массив данных для всплывающих подсказок
  45. ; Формат массива:
  46. ;   1 DWORD - сохраненный адрес обработчика
  47. ;   2 DWORD - адрес подсказки
  48. tt_data rd  (TOOLTIPS_COUNT*2)
Для добавления подсказок к элементам диалогового окна я написал отдельную процедуру, использующую субклассирование. Она же является процедурой, создающей исходное окно подсказки, если оно до этого не было создано. Окну подсказки присваивается максимальная ширина, определяемая константой TOOLTIP_WIDTH, и для большей изящности добавляется эффект тени.

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

Поле EDIT для ввода шестнадцатеричных цифр

23.08.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Поле для ввода только цифр организовать несложно, для этого достаточно просто прописать в ресурсах у нужного поля флаг ES_NUMBER. После этого с клавиатуры в это поле можно будет ввести только символ из интервала "0" - "9". Впрочем этот ничуть не мешает через Ctrl+C / Ctrl+V затолкать в него все что угодно, вплоть до непечатных бинарных данных. А как сделать поле, в которое можно вводить с клавиатуры только шестнадцатеричные цифры? Ведь там могут быть не только символы с десятичными цифрами, но и символы "A" - "F", которые также являются шестнадцатеричными цифрами. Это делается через субклассирование. Мы уже рассмотрели один пример субклассирования, превратив поле EDIT в гиперссылку, и там же определили алгоритм обработчика субклассированного элемента. Как и в прошлый раз, субклассирование должно выполняться на этапе инициализации диалогового окна.
  1. ; Сегмент данных
  2. section '.data' data readable writeable  
  3. OldProc dd ?    ; Адрес предыдущего обработчика
  4.  
  5. ; Сегмент кода
  6. section '.code' code readable executable
  7.         ...
  8.         ; Субклассирование на этапе инициализации окна
  9.         invoke  GetDlgItem,[hwnddlg],ID_HEX
  10.         ; Установить наш собственный обработчик
  11.         invoke  SetWindowLong,eax,GWL_WNDPROC,EditWindowProc
  12.         ; Сохранить хэндл предыдущего обработчика
  13.         mov     [OldProc],eax
  14.         ...
Здесь все почти то же самое, разница будет лишь в обрабатываемых сообщениях. Соответственно, если будет несколько полей ввода, то надо субклассировать каждое из них отдельно.

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

gzuncompress и gzinflate: Assembler vs PHP

11.08.2009 | Категория: Темная сторона Силы | Автор: ManHunter
При разработке проекта Massacre возникла необходимость реализовать функции распаковки PHP-кода на Ассемблере. В этой статье я распишу все выкладки по этому вопросу. Кому-нибудь пригодится - хорошо, не пригодится - оставлю для себя, чтобы не забыть. Как всегда, начнем с теории. Функции gzuncompress и gzinflate обратны к функциям gzcompress и gzdeflate, соответственно. Все они используют алгоритм сжатия LZW, который также используется в бесплатной библиотеке zlib. Сперва скачаем эту библиотеку и воспользуемся Ассемблером, чтобы сжать какую-нибудь эталонную строку.
  1. format PE GUI 4.0
  2. entry start
  3.  
  4. include 'win32a.inc'
  5.  
  6. section '.data' data readable writeable
  7.  
  8. strr    db 'ManHunter'  ; Строка для компрессии
  9. lend    = $-strr
  10. bsize   = 1000
  11.  
  12. blen    dd bsize
  13.  
  14. tmp     rb bsize
  15. tmp2    rb bsize
  16. tmp3    rb bsize
  17.  
  18. mask    db '%.2X ',0
  19.  
  20. ;----------------------------------------------------------
  21.  
  22. section '.code' code readable executable
  23. start:
  24.  
  25.         invoke  compress,tmp,blen,strr,dword lend
  26.  
  27.         mov     ecx,[blen]
  28.         mov     esi,tmp
  29. @@:
  30.         push    ecx
  31.         movzx   eax,byte [esi]
  32.         invoke  wsprintf,tmp2,mask,eax
  33.         add     esp,12
  34.         invoke  lstrcat,tmp3,tmp2
  35.         inc     esi
  36.         pop     ecx
  37.         loop    @b
  38.  
  39.         invoke  MessageBox,HWND_DESKTOP,tmp3,NULL,MB_OK
  40.         invoke  ExitProcess,0
  41.  
  42. ;----------------------------------------------------------
  43.  
  44. section '.idata' import data readable writeable
  45.  
  46. library kernel32,"kernel32.dll",\
  47.         user32,"user32.dll",\
  48.         zlib,"zlib1.dll"
  49.  
  50. include "apia\kernel32.inc"
  51. include "apia\user32.inc"
  52.  
  53.   import zlib,\
  54.          compress,'compress'
В окне будет показана следующая строка:

78 9C F3 4D CC F3 28 CD 2B 49 2D 02 00 11 11 03 93
Часть строки я специально выделил красным цветом, дальше будет понятно зачем это сделано.

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

Создание диалоговых окон с тенью

03.08.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодня разберем очередное украшательство для ваших программ, а именно тень от диалоговых окон. Обычная тень создается штатными средствами системы, но поддерживается только начиная с Windows XP. Для этого требуется, чтобы стиль окна включал в себя флаг CS_DROPSHADOW, и здесь есть одна тонкость: этот флаг нельзя прописать в ресурсах, а надо устанавливать при инициализации диалогового окна. В обработчике инициализации должен быть такой код:
  1.         ...
  2.         ; Определить константу CS_DROPSHADOW
  3.         CS_DROPSHADOW = 00020000h
  4.         ; Получить текущее значение стиля окна
  5.         invoke  GetWindowLong,[hwnddlg],GCL_STYLE
  6.         ; Добавить к нему атрибут тень
  7.         or      eax,CS_DROPSHADOW
  8.         ; Установить новый стиль окна
  9.         invoke  SetClassLong,[hwnddlg],GCL_STYLE,eax   
  10.         ...
Тут есть плюсы: корректно поддерживаются окна любой нестандартной и сложной формы, а все следующие окна процесса автоматически создаются сразу с тенью. Но есть один странный момент. Несмотря на то, что дочерние окна сперва создаются с корректной тенью, при любом перемещении их над родительским окном тени родительского и дочернего окна сливаются в одну. Пример такого нездорового явления природы показан на скриншоте.

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

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