Образ мышления: Assembler
То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал
Образ мышления: Assembler - Карта сайта
Блокировка автовыделения текста в поле EDIT
01.04.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
При создании диалогового окна, а также при перемещении по его элементам клавишей табуляции, текст в полях типа EDIT автоматически выделяется. Это стандартное поведение системы, так предусмотрено разработчиками Windows. Интересный вопрос, почему сделано именно так. Может быть самому Биллу Гейтсу было лениво нажимать кнопки Ctrl+A перед копированием текста из форм, может быть еще что-то, ответа я не знаю. Но зато у меня есть ответ на другой вопрос: можно ли сделать так, чтобы текст в поле EDIT автоматически не выделялся?Перед тем, как принять решение о (не)выделении текста в поле EDIT, система посылает элементу диалогового окна сообщение WM_GETDLGCODE, которое должно вернуть соответствующий набор флагов. Так вот, если в ответе взведен флаг DLGC_HASSETSEL, то текст выделяется. Несложно догадаться, что по умолчанию этот флаг взводится всегда. При этом сообщение WM_GETDLGCODE самим диалоговым окном никак не обрабатывается, так что нужно воспользоваться уже известным нам субклассированием. Будь то разовое для конкретного поля или универсальное субклассирование, не важно.
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- OldProc dd ? ; Адрес предыдущего обработчика
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Субклассирование на этапе инициализации окна
- invoke GetDlgItem,[hwnddlg],ID_SUB
- ; Установить наш собственный обработчик
- invoke SetWindowLong,eax,GWL_WNDPROC,EditWindowProc
- ; Сохранить хэндл предыдущего обработчика
- mov [OldProc],eax
- ...
Читать статью целиком »
Просмотров: 1031 | Комментариев: 2
Приложение с постоянно активным окном
17.03.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
В Windows, когда окно становится активным или наоборот теряет фокус, меняется его визуальный стиль. В зависимости от выбранной темы, меняется цвет кнопок в заголовке, увеличивается или уменьшается тень от окна, да и сам заголовок тоже меняет цвет. А можно ли сделать так, чтобы окно не меняло визуальный стиль? Можно. Реализуется это таким несложным трюком. Когда окну надо поменять визуальный стиль в зависимости от активности, ему отправляется сообщение WM_NCACTIVATE с соответствующим параметром. Значит в наше приложение надо добавить обработку этого сообщения.Code (Assembler) : Убрать нумерацию
- ; (Де)активировать заголовок окна?
- cmp [msg],WM_NCACTIVATE
- je .activate_window
- ...
- ...
- ...
- .activate_window:
- ; Деактивировать?
- cmp [wparam],FALSE
- jne @f
- ; Оставить заголовок активным
- mov [wparam],TRUE
- @@:
- ; Отправить сообщение дальше
- invoke DefWindowProc,[hwnddlg],[msg],[wparam],[lparam]
- jmp .processed
Конечно, возникает логичный вопрос зачем это вообще все надо? Например, ваше приложение создает виджет или тулбар в виде окна, которое должно постоянно находиться на экране. Так вот, для таких окон как раз желательно применить этот трюк, чтобы они выглядели всегда одинаково, неважно, активен виджет или нет.
Читать статью целиком »
Просмотров: 992 | Комментариев: 0
Поле EDIT для ввода десятичных цифр
26.02.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Как известно, если элементу диалогового окна типа EDIT установить флаг ES_NUMBER, то ввести в него можно будет только символы из интервала "0" - "9". Это в теории. На практике же в это поле через Ctrl+V или контекстное меню совершенно спокойно можно вставить любые данные, о чем даже написано в официальной документации. А еще в это поле нельзя ввести отрицательное число. Таким образом, практическая ценность ES_NUMBER приближается к нулю. Давайте учтем все эти недостатки и сделаем собственное, правильное поле EDIT для ввода десятичных цифр.Чтобы полностью контролировать ввод, надо будет воспользоваться субклассированием, заменив стандартную процедуру обработки на собственную. Это мы уже делали не раз, ничего нового тут нет.
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- OldProc dd ? ; Адрес предыдущего обработчика
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Субклассирование на этапе инициализации окна
- invoke GetDlgItem,[hwnddlg],ID_SUB
- ; Установить наш собственный обработчик
- invoke SetWindowLong,eax,GWL_WNDPROC,EditWindowProc
- ; Сохранить хэндл предыдущего обработчика
- mov [OldProc],eax
- ...
Читать статью целиком »
Просмотров: 1183 | Комментариев: 13
Как узнать раскладку клавиатуры другого приложения
21.01.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодня разберем, как можно узнать раскладку клавиатуры, которая активна в окне того или иного приложения. Также она может называться идентификатор языка ввода. С оконными приложениями все просто. Зная хэндл окна, через GetWindowThreadProcessId получаем идентификатор процесса, которому принадлежит исследуемое окно, а затем с помощью функции GetKeyboardLayout получаем код раскладки клавиатуры, которая активна в этом окне. Для консольных окон немного сложнее, так как они не реагируют на GetKeyboardLayout. Но это можно сделать при помощи недокументированной функции GetConsoleKeyboardLayoutName, которая возвращает код раскладки клавиатуры в виде строки. Просто так работать с консолью нельзя, для этого надо предварительно приаттачиться к процессу консольного окна, а после получения нужных данных отключиться от него.Code (Assembler) : Убрать нумерацию
- ; Получить активное окно
- invoke GetForegroundWindow
- ; Получить идентификатор процесса
- invoke GetWindowThreadProcessId,eax,pID
- mov ebx,eax
- ; Это консольное окно?
- invoke AttachConsole,[pID]
- or eax,eax
- jz .loc_gui
- .loc_console:
- ; Получить раскладку консольного окна
- invoke GetConsoleKeyboardLayoutName,buff
- or eax,eax
- jnz @f
- ; Не получилось, отключиться от консоли
- invoke FreeConsole
- ; Попробовать получить раскладку как у оконного приложения
- jmp .loc_gui
- @@:
- ...
- ; В buff строка с кодом раскладки типа "00000419"
- ...
- ; Просто отключиться от консоли
- invoke FreeConsole
- jmp .loc_done
- .loc_gui:
- ; Получить идентификатор раскладки клавиатуры
- invoke GetKeyboardLayout,ebx
- and eax,0xFFFF
- ...
- ; В EAX код раскладки
- ...
- .loc_done:
- ...
Читать статью целиком »
Просмотров: 1439 | Комментариев: 10
Отслеживание изменения системного времени
23.12.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Отслеживание изменения системного времени
Если ваша программа работает с системным временем, то хорошей практикой будет возможность отслеживать факт его изменения. Это может быть как ручное изменение настроек даты и времени через Панель управления, так и программное изменение времени функциями типа SetSystemTime или SetLocalTime, сути не меняет. Соответственно, при наступлении такого события ваша программа должна переустановить какие-то свои внутренние таймеры, проконтролировать и пересчитать интервалы между процессами и т.п.
Читать статью целиком »
Просмотров: 1565 | Комментариев: 0