Быстрый поиск
Введите фрагмент названия статьи для поиска
Анимация окон с помощью функции AnimateWindow
16.09.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter
Когда-то давно я показывал, как можно реализовать анимацию окна вручную. Сейчас покажу, как подобная анимация делается штатными функциями Windows, а точнее одной единственной функцией AnimateWindow. Но сперва некоторое количество констант, которые используются в программе, но про которые не знает FASM.Code (Assembler) : Убрать нумерацию
- AW_HOR_POSITIVE = 0x00000001
- AW_HOR_NEGATIVE = 0x00000002
- AW_VER_POSITIVE = 0x00000004
- AW_VER_NEGATIVE = 0x00000008
- AW_CENTER = 0x00000010
- AW_HIDE = 0x00010000
- AW_ACTIVATE = 0x00020000
- AW_SLIDE = 0x00040000
- AW_BLEND = 0x00080000
Code (Assembler) : Убрать нумерацию
- cmp [msg],WM_INITDIALOG
- je wminitdialog
- cmp [msg],WM_CLOSE
- je wmclose
- ...
- wminitdialog:
- ; Плавно развернуть окно из центра
- invoke AnimateWindow,[hwnddlg],300,AW_CENTER+AW_ACTIVATE
- ...
- wmclose:
- ; Плавно потушить окно при закрытии
- invoke AnimateWindow,[hwnddlg],300,AW_BLEND+AW_HIDE
- ...
Читать статью целиком »
Просмотров: 681 | Комментариев: 0
Установка точного размера клиентской области окна
19.06.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
Очередная тривиальная задача с нетривиальным решением и очередной пламенный привет разработчикам Windows. Начнем с задачи. Надо изменить размер окна таким образом, чтобы его клиентская область, то есть внутреннее содержимое без учета заголовка, рамок и полос прокрутки, стала четко заданной ширины и высоты. Создатели Windows, безусловно, позаботились о программистах, для решения этой задачи есть как минимум две функции - SetWindowPos и MoveWindow, все хорошо и замечательно, но... Как метко подметили в одном телесериале, все, что сказано до слова "но" - чушь собачья. Эти функции действительно выполняют свое предназначение, меняют размер окна, только применяют переданные им значения к внешней границе окна. При этом не учитываются ни визуальные темы, ни стили окна, ни наличие полос прокрутки, ни толщина рамки, короче, решения поставленной задачи "в лоб" дадут гарантированно неправильный результат.Размеры областей окна
К счастью, в Windows имеется вспомогательная функция AdjustWindowRectEx, которая используется как раз для подобных ситуаций. Он вычисляет фактические размеры окна, которые соответствуют заданным размерам его клиентской области. И вот здесь как раз учитываются стили, в том числе и расширенные, наличие у окна строки меню и установленная визуальная тема, но... Да-да, очередное "но". При расчете размеров никак не учитывается наличие в окне полос вертикальной и/или горизонтальной прокрутки. Они могут входить в размер клиентской области, а могут и не входить, в зависимости от задачи.
Читать статью целиком »
Просмотров: 885 | Комментариев: 2
Как сделать ProgressBar с надписью
21.04.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
Не перестаю удивляться, почему разработчики Microsoft с самого начала не реализовали "из коробки" очевиднейшие решения. Например, есть хороший и удобный элемент диалоговых окон - Progress Bar. Легко реализовать, удобно управлять, но по какой-то причине нет никаких инструментов, чтобы системными средствами наложить на индикатор прогресса какую-нибудь надпись типа "42% завершено". Градиентный ProgressBar мы уже делали, настала очередь реализовать ProgressBar с надписью.ProgressBar с надписью
Использовать стандартный элемент msctls_progress32 не будем, вместо него возьмем элемент EDIT или STATIC, как и в предыдущем примере. Полоса индикатора и надпись реализуется путем рисования прямо на канве элемента диалогового окна, которое выделено под индикатор.
Основная загвоздка заключается в том, что при отрисовке текста поверх индикатора прогресса, надо учитывать разницу в цвете фона и полосы выполненной части. Посмотрите на скриншоте, чтобы стало понятно, о чем идет речь. В некоторых случаях при определенной комбинации цветов можно использовать единый цвет, но это не самое хорошее решение. Так что сделаем все правильно.
Читать статью целиком »
Просмотров: 1094 | Комментариев: 1
Обработка Drag'n'Drop в разные поля ввода
28.03.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
В статье об обработке перетаскивания файлов я упомянул про раздельную обработку перетаскивания файлов в разные поля. В частности про вариант с субклассированием. Теперь расскажу, как это делается. Предположим, что у нас на форме есть три поля для выбора файла, причем каждое должно работать независимо.Code (Assembler) : Убрать нумерацию
- ; Разрешить каждому полю принимать файлы
- invoke GetDlgItem,[hwnddlg],ID_FILE1
- mov ebx,eax
- invoke DragAcceptFiles,ebx,TRUE
- ; Установить наш собственный обработчик
- invoke SetWindowLong,ebx,GWL_WNDPROC,EditWindowProc
- ; Сохранить хэндл предыдущего обработчика
- invoke SetWindowLong,ebx,GWL_USERDATA,eax
- invoke GetDlgItem,[hwnddlg],ID_FILE2
- mov ebx,eax
- invoke DragAcceptFiles,ebx,TRUE
- ; Установить наш собственный обработчик
- invoke SetWindowLong,ebx,GWL_WNDPROC,EditWindowProc
- ; Сохранить хэндл предыдущего обработчика
- invoke SetWindowLong,ebx,GWL_USERDATA,eax
- invoke GetDlgItem,[hwnddlg],ID_FILE3
- mov ebx,eax
- invoke DragAcceptFiles,ebx,TRUE
- ; Установить наш собственный обработчик
- invoke SetWindowLong,ebx,GWL_WNDPROC,EditWindowProc
- ; Сохранить хэндл предыдущего обработчика
- invoke SetWindowLong,ebx,GWL_USERDATA,eax
Читать статью целиком »
Просмотров: 648 | Комментариев: 3
MessageBox с чекбоксом "Больше не показывать"
04.10.2021 | Категория: Образ мышления: Assembler | Автор: ManHunter
Еще одна хорошая практика взаимодействия с пользователем - окно сообщения с чекбоксом "Больше не показывать это диалоговое окно". Таким образом и приложение выполняет свою работу по уведомлению пользователя о каком-то периодическом событии, и пользователь сам решает, желает ли он наблюдать это уведомление в дальнейшем. Делается это при помощи стандартной функции SHMessageBoxCheck. По параметрам эта функция очень похожа на вызов MessageBox, но поддерживает ограниченное количество стилей и не весь набор кнопок, а также обязательно требует текстовую строку с уникальным идентификатором этого сообщения. В остальном все сводится к единственному вызову, типа такого:Code (Assembler) : Убрать нумерацию
- ; Уникальный идентификатор окна сообщения
- szUID db '{D9108BA3-9A61-4398-BFBC-B02102C77E8A}',0
- ...
- ; Значение по умолчанию
- DEFAULT_RESULT = 0
- ; Вывести окно сообщения с галочкой "Больше не показывать"
- invoke SHMessageBoxCheck,HWND_DESKTOP,\
- szMess,szTitle,MB_YESNO+MB_ICONEXCLAMATION,\
- DEFAULT_RESULT,szUID
- ; EAX = выбранная кнопка или DEFAULT_RESULT
Читать статью целиком »
Просмотров: 1047 | Комментариев: 6