Blog. Just Blog

Образ мышления: Assembler

То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал Образ мышления: Assembler - Карта сайта

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

07.08.2022 | Категория: Образ мышления: Assembler | Автор: ManHunter
Как известно, контроль учетных записей (UAC) является основополагающим компонентом общей концепции безопасности Microsoft. UAC помогает уменьшить воздействие вредоносных программ и защищать данные от несанкционированного доступа. Если для работы ваших приложений понадобится доступ к защищенным объектам, то система выдаст соответствующее предупреждение с запросом о предоставлении таких прав. Особенно это актуально для системы Win10 и выше, где Проводник всегда запускается в контексте безопасности обычного пользователя и, соответственно, все запущенные в нем процессы также будут иметь обычные права. Для повышения прав приложения можно запускать от имени Администратора.

Для того, чтобы определить, как именно было запущено ваше приложение, то есть в нормальном режиме или от имени Администратора, есть специальные функции. Но сперва, как обычно, не известные FASM константы.
  1. TOKEN_QUERY_SOURCE = 0x0010
  2. TOKEN_QUERY        = 8h
  3. TokenElevationType = 18
  4.  
  5. TokenElevationTypeDefault = 1
  6. TokenElevationTypeFull    = 2
  7. TokenElevationTypeLimited = 3
Теперь осталось открыть токен текущего процесса при помощи функции OpenProcessToken и затем через функцию GetTokenInformation получить из него информацию об уровне доступа:
  1.         invoke  GetCurrentProcess
  2.         invoke  OpenProcessToken,eax,TOKEN_QUERY,hToken
  3.         invoke  GetTokenInformation,[hToken],TokenElevationType,tet,4,dSize
На выходе получим одно из возможных значений: TokenElevationTypeDefault - UAC совсем отключен или процесс запущен от обычного пользователя, не являющегося Администратором. TokenElevationTypeFull - родительский процесс имеет права обычного пользователя, но дочерний процесс был запущен от имени Администратора. TokenElevationTypeLimited - как родительский процесс, так и запущенный, оба имеют права обычного пользователя.

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

Встроенный браузер в приложении на Ассемблере

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

Встроенный браузер в приложении на Ассемблере

Сегодня будем рисовать свой браузер, а точнее внедрять фрейм web-браузера в интерфейс нашего приложения. Нечто подобное мы уже делали, но там были отдельные страницы, а сейчас полноценный браузер, встроенный в приложение. Языком исполнения, естественно, будет Ассемблер.

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

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

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

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

Автовыделение текста в поле 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. Все очень просто.

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

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

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


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

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

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

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