Blog. Just Blog

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

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

Как сделать иконку на кнопке справа от текста

25.06.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
При помощи сообщение BM_SETIMAGE на кнопку можно добавить иконку, в обычном режиме она будет располагаться слева от надписи. Для одной из моих программ понадобилось разместить иконку на кнопке справа от надписи. Да, я в курсе про самостоятельную отрисовку кнопок, про субклассирование и прочие навороты, но хотелось обойтись малой кровью. Поразмыслив, я решил задачу с помощью расширенного стиля окна WS_EX_LAYOUTRTL, который применяется к отдельно взятой кнопке. По прямому назначению он используется для корректной отрисовки содержимого окна на арабском или других языках с направлением письма справа-налево. Как оказалось, для иконок это тоже неплохо работает.

Вот код для переключения иконки на положение справа. Подразумевается, что иконка уже ранее была установлена на кнопку при инициализации окна или при создании элемента управления.
  1.         ; Установить иконку справа от текста
  2.         invoke  GetDlgItem,[hwnddlg],ID_BUTTON
  3.         mov     ebx,eax
  4.         ; Добавить стиль Right-to-Left
  5.         invoke  GetWindowLong,ebx,GWL_EXSTYLE
  6.         or      eax,WS_EX_LAYOUTRTL
  7.         invoke  SetWindowLong,ebx,GWL_EXSTYLE,eax
  8.         ; Обновить иконку
  9.         invoke  SendMessage,ebx,BM_GETIMAGE,IMAGE_ICON,0
  10.         invoke  SendMessage,ebx,BM_SETIMAGE,IMAGE_ICON,eax
Для возврата обычного положения иконки нужно убрать WS_EX_LAYOUTRTL из расширенного стиля кнопки.
  1.         ; Установить иконку слева от текста
  2.         invoke  GetDlgItem,[hwnddlg],ID_BUTTON
  3.         mov     ebx,eax
  4.         ; Убрать стиль Right-to-Left
  5.         invoke  GetWindowLong,ebx,GWL_EXSTYLE
  6.         and     eax,not WS_EX_LAYOUTRTL
  7.         invoke  SetWindowLong,ebx,GWL_EXSTYLE,eax
  8.         ; Обновить иконку
  9.         invoke  SendMessage,ebx,BM_GETIMAGE,IMAGE_ICON,0
  10.         invoke  SendMessage,ebx,BM_SETIMAGE,IMAGE_ICON,eax
После смены расширенного стиля надо обязательно обновить иконку на кнопке. Чтобы не заморачиваться с повторной загрузкой и не хранить данные, кому какая иконка назначена, достаточно получить хэндл имеющейся на кнопке иконки и тут же назначить его обратно.

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

Форшмак

22.06.2022 | Категория: А еще я туда ем! | Автор: ManHunter

Форшмак

Форшмак - холодная закуска из измельченной сельди, традиционно приписываемая к еврейской кухне. Рецептов и технологий приготовления форшмака много, так что я на оригинальность не претендую.

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

Автовыделение текста в поле EDIT

20.06.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
Продолжаем улучшать базовый функционал стандартного поля ввода. При двойном клике на слове, находящемся в поле EDIT, это слово выделяется. Это хорошо и правильно. При двойном клике на пустом поле, которое находится справа от последнего символа текста, выделяется последнее слово в строке. И вот это, как мне кажется, неправильное поведение. По логике должна выделяться вся строка, что-то похожее реализовано в адресной строке браузеров. Вроде бы мелочь, но именно из таких незначительных деталей складывается общее впечатление о вашей программе. Давайте добавим чуточку красоты в этот мир.

При инициализации родительского окна установим свой субклассированный обработчик для нужного поля ввода. Эта тема должна быть вам уже хорошо знакома, она не раз обсуждалась на сайте. А вот сам обработчик:
  1. ;------------------------------------------------
  2. ; Субклассированный обработчик
  3. ;------------------------------------------------
  4. proc EditWindowProc hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
  5.         ; Даблклик левой кнопкой мыши?
  6.         cmp     [uMsg],WM_LBUTTONDBLCLK
  7.         je      .dblclick
  8. .char_ok:
  9.         ; Передать управление предыдущему обработчику
  10.         invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
  11.         ret
  12. .dblclick:
  13.         ; Передать управление предыдущему обработчику
  14.         invoke  CallWindowProc,[OldProc],[hEdit],[uMsg],[wParam],[lParam]
  15.  
  16.         ; Получить информацию о ближайшем символе, рядом с которым
  17.         ; произошло событие двойного клика
  18.         ; В lParam находятся координаты произошедшего события
  19.         invoke  SendMessage,[hEdit],EM_CHARFROMPOS,0,[lParam]
  20.         ; Сохранить для сравнения
  21.         mov     ebx,eax
  22.  
  23.         ; Получить длину текста в поле ввода
  24.         invoke  GetWindowTextLength,[hEdit]
  25.         ; Событие произошло за границами содержимого?
  26.         cmp     eax,ebx
  27.         jne     @f
  28.         ; Выделить весь текест в поле ввода
  29.         invoke  SendMessage,[hEdit],EM_SETSEL,0,eax
  30. @@:
  31.         ret
  32. endp
При поступлении в обработчик события WM_LBUTTONDBLCLK, получаем координаты, где оно произошло. Затем с помощью EM_CHARFROMPOS узнаем позицию ближайшего символа строки, рядом с которым произошло событие. Если эта позиция равна длине строки, то выделяем весь текст в поле ввода при помощи EM_SETSEL. Все очень просто.

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

Установка точного размера клиентской области окна

19.06.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
Очередная тривиальная задача с нетривиальным решением и очередной пламенный привет разработчикам Windows. Начнем с задачи. Надо изменить размер окна таким образом, чтобы его клиентская область, то есть внутреннее содержимое без учета заголовка, рамок и полос прокрутки, стала четко заданной ширины и высоты. Создатели Windows, безусловно, позаботились о программистах, для решения этой задачи есть как минимум две функции - SetWindowPos и MoveWindow, все хорошо и замечательно, но... Как метко подметили в одном телесериале, все, что сказано до слова "но" - чушь собачья. Эти функции действительно выполняют свое предназначение, меняют размер окна, только применяют переданные им значения к внешней границе окна. При этом не учитываются ни визуальные темы, ни стили окна, ни наличие полос прокрутки, ни толщина рамки, короче, решения поставленной задачи "в лоб" дадут гарантированно неправильный результат.


Размеры областей окна

К счастью, в Windows имеется вспомогательная функция AdjustWindowRectEx, которая используется как раз для подобных ситуаций. Он вычисляет фактические размеры окна, которые соответствуют заданным размерам его клиентской области. И вот здесь как раз учитываются стили, в том числе и расширенные, наличие у окна строки меню и установленная визуальная тема, но... Да-да, очередное "но". При расчете размеров никак не учитывается наличие в окне полос вертикальной и/или горизонтальной прокрутки. Они могут входить в размер клиентской области, а могут и не входить, в зависимости от задачи.

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

Выставка "Давай играть, как раньше"

17.06.2022 | Категория: Жизнь в оффлайне | Автор: ManHunter

Выставка "Давай играть, как раньше"

Выставка "Давай играть, как раньше" предлагает всем взрослым вспомнить о том, что они тоже когда-то были детьми, рассказать детям и внукам о своем детстве и показать им, что было в игрушечном арсенале их пап и мам, бабушек и дедушек. Куклы, грузовики, железная дорога, миниатюрные швейные машинки и экзотические животные... Лучшие художники и инженеры страны работали над тем, чтобы наши дети развивались правильно.

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

prev 01 02 03 04 05 06 07 08 09 ... 355
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2022
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.09 сек. / MySQL: 3 (0.0214 сек.) / Память: 5 Mb
Наверх