Blog. Just Blog

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

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

Приложение с постоянно активным окном

17.03.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
В Windows, когда окно становится активным или наоборот теряет фокус, меняется его визуальный стиль. В зависимости от выбранной темы, меняется цвет кнопок в заголовке, увеличивается или уменьшается тень от окна, да и сам заголовок тоже меняет цвет. А можно ли сделать так, чтобы окно не меняло визуальный стиль? Можно. Реализуется это таким несложным трюком. Когда окну надо поменять визуальный стиль в зависимости от активности, ему отправляется сообщение WM_NCACTIVATE с соответствующим параметром. Значит в наше приложение надо добавить обработку этого сообщения.
  1.         ; (Де)активировать заголовок окна?
  2.         cmp     [msg],WM_NCACTIVATE
  3.         je      .activate_window
  4.         ...
  5.         ...
  6.         ...
  7. .activate_window:
  8.         ; Деактивировать?
  9.         cmp     [wparam],FALSE
  10.         jne     @f
  11.         ; Оставить заголовок активным
  12.         mov     [wparam],TRUE
  13. @@:
  14.         ; Отправить сообщение дальше
  15.         invoke  DefWindowProc,[hwnddlg],[msg],[wparam],[lparam]
  16.         jmp     .processed
Таким образом, когда Windows дает окну команду перерисоваться в неактивном виде, наше приложение принудительно заставляет окно сохранять активный визуальный стиль.

Конечно, возникает логичный вопрос зачем это вообще все надо? Например, ваше приложение создает виджет или тулбар в виде окна, которое должно постоянно находиться на экране. Так вот, для таких окон как раз желательно применить этот трюк, чтобы они выглядели всегда одинаково, неважно, активен виджет или нет.

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

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

26.02.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Как известно, если элементу диалогового окна типа EDIT установить флаг ES_NUMBER, то ввести в него можно будет только символы из интервала "0" - "9". Это в теории. На практике же в это поле через Ctrl+V или контекстное меню совершенно спокойно можно вставить любые данные, о чем даже написано в официальной документации. А еще в это поле нельзя ввести отрицательное число. Таким образом, практическая ценность ES_NUMBER приближается к нулю. Давайте учтем все эти недостатки и сделаем собственное, правильное поле 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_SUB
  10.         ; Установить наш собственный обработчик
  11.         invoke  SetWindowLong,eax,GWL_WNDPROC,EditWindowProc
  12.         ; Сохранить хэндл предыдущего обработчика
  13.         mov     [OldProc],eax
  14.         ...
Для одиночного поля можно ограничиться этим решением, но если таких полей предполагается несколько, то лучше воспользоваться универсальным субклассированием.

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

Окно с возможностью клика сквозь него

15.11.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter

Окно с возможностью клика сквозь него

Некоторые улучшайзеры интерфейсов типа Actual Window Manager позволяют накладывать на окна так называемый эффект "призрачности". В этом режиме окно продолжает отображаться на экране, но все клики мышкой на области окна проходят сквозь него, как будто окна вовсе нет. Давайте разберем, как это делается. А для большего эффекта "призрачное" окно можно сделать полупрозрачным.

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

Как программно свернуть все окна

04.09.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Есть разные способы программно свернуть все открытые окна. Простой и топорный вариант решения - эмуляция нажатия клавиш Win+M, которые и выполняют команду "Свернуть все окна". Делается это через последовательность вызовов keybd_event.
  1.         ; Эмуляция нажатия клавиш Win+M
  2.         invoke  keybd_event,VK_LWIN,0,0,NULL
  3.         invoke  Sleep,1
  4.         invoke  keybd_event,'M',0,0,NULL
  5.         invoke  Sleep,1
  6.         invoke  keybd_event,VK_LWIN,0,KEYEVENTF_KEYUP,NULL
Для обратного действия надо сэмулировать нажатие комбинации Win+Shift+M:
  1.         ; Эмуляция нажатия клавиш Win+Shift+M
  2.         invoke  keybd_event,VK_LWIN,0,0,NULL
  3.         invoke  Sleep,1
  4.         invoke  keybd_event,VK_LSHIFT,0,0,NULL
  5.         invoke  Sleep,1
  6.         invoke  keybd_event,'M',0,0,NULL
  7.         invoke  Sleep,1
  8.         invoke  keybd_event,VK_LSHIFT,0,KEYEVENTF_KEYUP,NULL
  9.         invoke  Sleep,1
  10.         invoke  keybd_event,VK_LWIN,0,KEYEVENTF_KEYUP,NULL
Таким же образом эмулируется нажатие комбинации Win+D - "Показать рабочий стол". Решение, в принципе, рабочее, но целиком полагаться на программную эмуляцию клавиатуры нельзя. Нажатие клавиш может перехватить или переопределить другое приложение, может быть заполнена системная очередь ввода, да мало ли чего.

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

Создание выпадающего списка (Combobox) с иконками

20.08.2019 | Категория: Образ мышления: Assembler | Автор: ManHunter
Ранее я рассказывал, как сделать простой комбобокс. Сейчас давайте усовершенствуем его, а точнее дополним строки списка иконками. Я уже делал подобное с меню, тут принцип точно такой же. К стилям комбобокса в ресурсах добавляется CBS_OWNERDRAWFIXED, что в дальнейшем позволит нам самостоятельно обрабатывать процесс отрисовки каждой строки выпадающего списка. Теорию и принцип работы вы можете почитать по приведенной ссылке, повторяться я не буду. В обработчик окна, в котором находится комбобокс, добавляется реакция на два события - это WM_MEASUREITEM, которое приходит перед отрисовкой строки, и WM_DRAWITEM, при котором мы будем рисовать эту строку.
  1.         cmp     [msg],WM_MEASUREITEM
  2.         je      wm_measure
  3.         cmp     [msg],WM_DRAWITEM
  4.         je      wm_drawitem
Начнем с первого обработчика. Тут система в параметре lParam сообщения передает нам структуру MEASUREITEMSTRUCT, в которой сообщает нашей программе тип объекта, который она планирует нарисовать, а также его идентификаторы и размеры прямоугольника, который он будет занимать.
  1. wm_measure:
  2.         ; Отрисовываем строку комбобокса?
  3.         mov     ebx,[lparam]
  4.         cmp     [ebx+MEASUREITEMSTRUCT.CtlType],ODT_COMBOBOX
  5.         jne     processed
  6.  
  7.         ; Высота строки комбобокса с учетом размера иконки
  8.         mov     [ebx+MEASUREITEMSTRUCT.itemHeight],26
  9.  
  10.         jmp     processed
Проверяем, если это комбобокс, то меняем его высоту на фиксированные 26 пикселов. Ширина остается без изменений. Обратите внимание, что тут не проверяется идентификатор комбобокса CtlID, так как в нашем примере он один единственный. В реальных проектах, когда на форме может быть более одного выпадающего списка, такие проверки надо выполнять в обязательном порядке.

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

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2022
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.12 сек. / MySQL: 3 (0.0558 сек.) / Память: 5 Mb
Наверх