Образ мышления: Assembler
То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал
Образ мышления: Assembler - Карта сайта
Как изменить цвет кнопок диалогового окна
17.11.2018 | Категория: Образ мышления: Assembler | Автор: ManHunter
Когда-то давно в одной из статей я рассказывал, как менять цвета различных элементов диалоговых окон Windows. Наверняка вы обратили внимание, что элемент типа BUTTON, то есть кнопка, выбивается из общей схемы и на изменение цвета не реагирует должным образом. Решить эту проблему все-таки можно, но для этого придется самостоятельно отрисовывать все компоненты кнопки - фон, рамку и надпись. Зато такой способ открывает неограниченные возможности по кастомизации кнопок.Первым делом в ресурсах или в функции создания кнопки через CreateWindow(Ex) надо дополнить стиль модифицируемой кнопки параметром BS_OWNERDRAW. С этого момента все функции по рисованию перекладываются на наше приложение. Для этого приложение должно обрабатывать сообщение WM_DRAWITEM. Окну-владельцу кнопки в параметре lParam этого сообщения передается указатель на структуру DRAWITEMSTRUCT, на основании которой мы и будем заниматься рисованием.
Code (Assembler) : Убрать нумерацию
- cmp [msg],WM_DRAWITEM
- je color_button
- ...
- ...
- color_button:
- ; Указатель на структуру DRAWITEMSTRUCT
- mov ebx,[lparam]
- ; Установить режим смешивания фоновых цветов
- invoke SetBkMode,[ebx+DRAWITEMSTRUCT.hDC],TRANSPARENT
- ; Кнопка активна?
- test [ebx+DRAWITEMSTRUCT.itemState],ODS_SELECTED
- jz @f
- invoke GetSysColor,COLOR_ACTIVEBORDER
- invoke CreatePen,PS_SOLID,1,eax
- invoke SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
- invoke GetSysColor,COLOR_3DLIGHT
- invoke CreateSolidBrush,eax
- invoke SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
- ; Прямоугольник с заливкой
- invoke Rectangle,[ebx+DRAWITEMSTRUCT.hDC],\
- [ebx+DRAWITEMSTRUCT.rcItem.left],\
- [ebx+DRAWITEMSTRUCT.rcItem.top],\
- [ebx+DRAWITEMSTRUCT.rcItem.right],\
- [ebx+DRAWITEMSTRUCT.rcItem.bottom]
- jmp loc_text
- @@:
- ; Установить цвет и стиль рамки
- invoke GetSysColor,COLOR_3DDKSHADOW
- invoke CreatePen,PS_SOLID,3,eax
- invoke SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
- ; Установить цвет фона
- invoke GetSysColor,COLOR_HIGHLIGHT
- invoke CreateSolidBrush,eax
- invoke SelectObject,[ebx+DRAWITEMSTRUCT.hDC],eax
- ; Прямоугольник с заливкой
- invoke Rectangle,[ebx+DRAWITEMSTRUCT.hDC],\
- [ebx+DRAWITEMSTRUCT.rcItem.left],\
- [ebx+DRAWITEMSTRUCT.rcItem.top],\
- [ebx+DRAWITEMSTRUCT.rcItem.right],\
- [ebx+DRAWITEMSTRUCT.rcItem.bottom]
- loc_text:
- ; Длина надписи на кнопке
- invoke GetWindowTextLength,[ebx+DRAWITEMSTRUCT.hwndItem]
- inc eax
- mov [len],eax
- invoke GetWindowText,[ebx+DRAWITEMSTRUCT.hwndItem],buff,[len]
- ; Установить цвет текста
- invoke SetTextColor,[ebx+DRAWITEMSTRUCT.hDC],0x0000FFFF
- ; Для нажатой кнопки сдвинуть текст вниз-вправо
- test [ebx+DRAWITEMSTRUCT.itemState],ODS_SELECTED
- jz @f
- ; Установить цвет текста
- invoke SetTextColor,[ebx+DRAWITEMSTRUCT.hDC],0x000000FF
- add [ebx+DRAWITEMSTRUCT.rcItem.left],2
- add [ebx+DRAWITEMSTRUCT.rcItem.top],2
- @@:
- ; Надпись на кнопке
- lea esi,[ebx+DRAWITEMSTRUCT.rcItem]
- invoke DrawText,[ebx+DRAWITEMSTRUCT.hDC],buff,[len],esi,\
- DT_SINGLELINE+DT_VCENTER+DT_CENTER
Читать статью целиком »
Просмотров: 1983 | Комментариев: 0
Получение данных из консольного окна другого приложения
02.11.2018 | Категория: Образ мышления: Assembler | Автор: ManHunter
Мы уже умеем перехватывать ввод и вывод консольных приложений, но этот способ работает только для тех процессов, которые мы сами запустили. Но иногда надо получать информацию из консольных приложений, которые уже были запущены в системе или могут быть запущены в дальнейшем, но не нами. А еще бывают консольные приложения, вывод которых невозможно перенаправить и, соответственно, невозможно получить описанным ранее способом. Для них также придется использовать способ из этой статьи.Для начала как всегда несколько структур, которые изначально не описаны в FASM. Они нам понадобятся для работы с консольным окном:
Code (Assembler) : Убрать нумерацию
- struct COORD
- X dw ?
- Y dw ?
- ends
- struct SMALL_RECT
- Left dw ?
- Top dw ?
- Right dw ?
- Bottom dw ?
- ends
- struct CONSOLE_SCREEN_BUFFER_INFO
- dwSize COORD
- dwCursorPosition COORD
- wAttributes dw ?
- srWindow SMALL_RECT
- dwMaximumWindowSize COORD
- ends
Читать статью целиком »
Просмотров: 1864 | Комментариев: 0
Как получить реальную версию Windows из режима совместимости
25.09.2018 | Категория: Образ мышления: Assembler | Автор: ManHunter
Как получить реальную версию Windows из режима совместимости
Одной из основных политик компании Microsoft является поддержка обратной совместимости программ, то есть программы для Windows, написанные даже очень давно, теоретически должны работать на современных системах. Один из механизмов обеспечения такой работоспособности - запуск программ в режиме совместимости. Достаточно в свойствах исполняемого файла указать, какую версию Windows надо использовать, и система при запуске программы будет эмулировать для нее окружение именно этой версии. Если при этом из программы попытаться получить версию Windows при помощи функции GetVersion, GetVersionEx или даже RtlGetVersion, то результат вернет версию эмулируемой ОС. А можно ли как-то определить, что программа запущена в режиме совместимости и получить реальную версию Windows, на которой она работает? Можно!
Читать статью целиком »
Просмотров: 2928 | Комментариев: 12
Особенности работы с контролом SysMonthCal32
07.09.2018 | Категория: Образ мышления: Assembler | Автор: ManHunter
Различная ширина SysMonthCal32 в разных локалях
При разработке одной из своих программ я столкнулся с интересной ситуацией. Никаких ракетных технологий, просто в диалоговом окне выводится стандартный виджет календарика через контрол SysMonthCal32. Я работаю в русской версии Windows и наивно предположил, что размеры виджета календарика всегда должны как-то вписываться в те границы, которые я ему определил. Но, как вы можете видеть на этих скриншотах, ширина контрола с календариком заметно отличается в зависимости от установленной в системе локали, на что мне указал один из пользователей (Mufasa, спасибо!). Вариантов нет, пришлось изучить этот вопрос.
Читать статью целиком »
Просмотров: 1573 | Комментариев: 2
Как узнать загруженность процессора
24.08.2018 | Категория: Образ мышления: Assembler | Автор: ManHunter
Как узнать загруженность процессора
Очередная интересная задача для программирования - узнать загруженность центрального процессора компьютера в процентах. Проблема в том, что система ни через какие API не предоставляет такого значения, как "загруженность", его просто нет. Зато есть хорошая функция GetSystemTimes, которая возвращает три значения: время, которое система бездействовала, время работы системы в режиме ядра и время работы системы в пользовательском режиме. Узнав разницу значений между этими таймингами за определенный интервал, можно определить загруженность процессора за этот интервал. На многоядерных системах эта функция возвращает суммарные значения по всем ядрам.
Читать статью целиком »
Просмотров: 2007 | Комментариев: 9