Blog. Just Blog

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

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

Управление кнопками Minimize, Maximize, Help и Close в заголовке окна

15.04.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Очередная развлекуха на Ассемблере. Сегодня мы будем всячески управлять стандартными кнопками в заголовке окна. Это могут быть Minimize, Maximize, Help и Close, для каждой из них свои правила. Для начала, чтобы в заголовке окна появились кнопки, оно должно быть создано со стилями WS_CAPTION и WS_SYSMENU, этого достаточно, чтобы появилась кнопка Close. Кнопки Minimize и Maximize появляются при добавлении в стили окна хотя бы одного значения WS_MAXIMIZEBOX или WS_MINIMIZEBOX, причем они неразрывны как Ленин и Партия, в любом случае появятся обе, а комбинацией стилей только регулируется их активность. Для появления кнопки Help в расширенном стиле окна должно присутствовать значение WS_EX_CONTEXTHELP, причем кнопки Minimize/Maximize и кнопка Help взаимоисключающие, одновременно в заголовке окна они присутствовать не могут. Почему так сделано - непонятно.

С теорией закончили, переходим к практике. В различных ситуациях может понадобиться отключение или включение определенных кнопок в заголовке окна. Как несложно догадаться, состояния кнопок Minimize, Maximize и Help регулируются манипуляциями со стилями окна:
  1. .enable_min:
  2.         ; Активировать кнопку Minimize
  3.         invoke  GetWindowLong,[hwnddlg],GWL_STYLE
  4.         or      eax,WS_MINIMIZEBOX
  5.         invoke  SetWindowLong,[hwnddlg],GWL_STYLE,eax
  1. .disable_min:
  2.         ; Отключить кнопку Minimize
  3.         invoke  GetWindowLong,[hwnddlg],GWL_STYLE
  4.         and     eax,not WS_MINIMIZEBOX
  5.         invoke  SetWindowLong,[hwnddlg],GWL_STYLE,eax
  1. .enable_max:
  2.         ; Активировать кнопку Maximize
  3.         invoke  GetWindowLong,[hwnddlg],GWL_STYLE
  4.         or      eax,WS_MAXIMIZEBOX
  5.         invoke  SetWindowLong,[hwnddlg],GWL_STYLE,eax
  1. .disable_max:
  2.         ; Отключить кнопку Maximize
  3.         invoke  GetWindowLong,[hwnddlg],GWL_STYLE
  4.         and     eax,not WS_MAXIMIZEBOX
  5.         invoke  SetWindowLong,[hwnddlg],GWL_STYLE,eax
Если уж делать совсем все правильно, то было бы неплохо при активации одной из кнопок Minimize или Maximize на всякий случай удалять из расширенного стиля окна взаимоисключающее значение WS_EX_CONTEXTHELP. Также имейте в виду, что при одновременном отключении обеих кнопок, они просто исчезнут.

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

Переключение окна в полноэкранный режим и обратно

14.04.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Смотрел тут очередную киношку на своем любимом плеере Light Alloy и впервые за много лет обратил внимание, как он переключается в полноэкранный режим, а затем обратно. Нет, про само переключение, естественно, я знал и использовал, просто внезапно захотелось сделать что-нибудь подобное для оконного приложения на не менее любимом Ассемблере.

Вот обработчик переключения. Он будет двухпозиционный, то есть если окно уже находится в полноэкранном режиме, то вернет его к исходному виду, а иначе развернет на полный экран. Естественно, вы можете разделить его на два отдельных события или оставить только нужную часть, например, только переход в полноэкранный режим.
  1.         invoke  GetWindowLong,[hwnddlg],GWL_STYLE
  2.         ; EBX - текущий стиль окна
  3.         mov     ebx,eax
  4.         test    ebx,WS_OVERLAPPEDWINDOW
  5.         jz      .fullscreen_off
  6.  
  7. .fullscreen_on:
  8.         and     ebx,not WS_OVERLAPPEDWINDOW
  9.         invoke  SetWindowLong,[hwnddlg],GWL_STYLE,ebx
  10.         invoke  ShowWindow,[hwnddlg],SW_MAXIMIZE
  11.         jmp     .processed
  12.  
  13. .fullscreen_off:
  14.         or      ebx,WS_OVERLAPPEDWINDOW
  15.         invoke  SetWindowLong,[hwnddlg],GWL_STYLE,ebx
  16.         invoke  ShowWindow,[hwnddlg],SW_RESTORE
  17.         jmp     .processed
При наличии нескольких мониторов окно будет развернуто на том, где оно в текущий момент находится. За видимость панели задач переживать не надо. Когда система обнаружит приложение, которое переключилось в полноэкранный режим, то панель задач будет спрятана автоматически. Дополнительных операций для этого выполнять не надо.

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

Способы отправки сообщений в Windows

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

Способы отправки сообщений в Windows

Любой разработчик программ под Windows наверняка так или иначе сталкивался с отправкой сообщений через функции SendMessage и PostMessage. При всей кажущейся простоте, у этих функций есть свои особенности, про которые будет полезно узнать, особенно начинающим программистам.

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

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

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

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

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

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

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