Blog. Just Blog

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

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

Загрузка иконки напрямую из памяти

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

Загрузка иконки напрямую из памяти

Уже который раз сталкиваюсь с тем, что для решения какой-нибудь простейшей задачи приходится сперва перекопать огромную кучу информации, а затем хитро извернуться, потому что штатных решений нет в принципе. Одна из таких задач выглядит на первый взгляд очень просто: в память загружен файл иконки, надо из него сделать хэндл HICON для дальнейшего использования.

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

Работа с иконками файлов на Ассемблере

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

Работа с иконками файлов на Ассемблере

Я уже рассказывал, как можно получить иконку из окна чужого приложения, сегодня тема будет похожей. Разница в том, что иконку мы будем получать из файла на диске. Применений для этого может быть много, например, чтобы отрисовать в вашем приложении красивый список файлов, нарисовать всплывающее меню, заменить иконку в собранном джойнере или патче. Для работы с иконками в WInAPI есть несколько функций, каждая со своими особенностями. В этой статье я попытаюсь подробно рассказать о них.

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

Меню с иконками на Ассемблере

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

Начнем создание собственных элементов интерфейса с того, что для каждого настраиваемого меню резервируется структура с данными следующего формата:
  1. struct MYMENU
  2.   hMenu      dd ?
  3.   itemWidth  dd ?
  4.   itemHeight dd ?
  5.   hasIcons   db ?
  6. ends
В это же время, все меню, которые требуют кастомизации, формируют массив структур и указателей на них. Список заканчивается нулевым DWORD'ом:
  1. menus   dd Menu1
  2.         dd Menu2
  3.         dd ?
  4.  
  5. Menu1   MYMENU
  6. Menu2   MYMENU
Описание полей структуры: hMenu - хэндл меню, itemWidth - ширина пункта меню в пикселах, itemHeight - высота пункта меню в пикселах, hasIcons - флаг, определяющий, будут или нет использоваться в меню иконки (1 - да, 0 - нет). Если иконки будут использоваться, то слева от текста пунктов меню резервируется место для них, в противном случае текст пункта будет отрисовываться прямо от края меню.

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

Правильное принудительное обновление иконок в трее

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

Суть задачи остается прежней: некое приложение аварийно завершило работу, в трее остался его значок. Нужно из своего приложения обновить системный трей таким образом, чтобы этот значок убрать. Все трудности этой задачи я подробно описал в статье по ссылке выше, поэтому повторяться не буду и перейду сразу к решению. За основу взят код получения списка иконок в трее. При переборе проверяется наличие окна, которому должна принадлежать иконка. Если окна нет, значит и иконки существовать не должно. Такие иконки удаляются при помощи функции Shell_NotifyIcon с параметром NIM_DELETE.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. ; Структура пользовательских данных иконки
  5. struct EXTRADATA
  6.         Wnd dd ?
  7.         uID dd ?
  8. ends
  9.  
  10. class1     db 'Shell_TrayWnd',0    ; Название класса окна трея
  11. class2     db 'TrayNotifyWnd',0    ; Название класса панели уведомлений
  12. class3     db 'SysPager',0         ; Трей
  13. class4     db 'ToolbarWindow32',0  ; Панель с иконками
  14.  
  15. ; Структура для кнопки
  16. button     TBBUTTON
  17. ; Структура для пользовательских данных иконки
  18. extra      EXTRADATA
  19. ; Структура для работы с иконкой в трее
  20. nid        NOTIFYICONDATA
  21.  
  22. hToolbar   dd ?    ; Хэндл окна с иконками
  23. IconsCount dd ?    ; Количество иконок в трее
  24. ProcId     dd ?    ; Id процесса
  25. hProcess   dd ?    ; Хэндл процесса
  26. lpData     dd ?    ; Указатель на блок памяти
  27. BytesRead  dd ?    ; Количество прочитанных символов
  1.         ; Найти окно трея
  2.         invoke  FindWindow,class1,NULL
  3.         or      eax,eax
  4.         jz      exit_process
  5.  
  6.         ; Найти панель уведомлений
  7.         invoke  FindWindowEx,eax,NULL,class2,NULL
  8.         or      eax,eax
  9.         jz      exit_process
  10.  
  11.         ; Найти трей
  12.         invoke  FindWindowEx,eax,NULL,class3,NULL
  13.         or      eax,eax
  14.         jz      exit_process
  15.  
  16.         ; Найти панель иконок в трее
  17.         invoke  FindWindowEx,eax,NULL,class4,NULL
  18.         or      eax,eax
  19.         jz      exit_process
  20.  
  21.         ; Сохранить хэндл окна с иконками
  22.         mov     [hToolbar],eax
  23.  
  24.         ; Получить количество иконок в трее
  25.         invoke  SendMessage,eax,TB_BUTTONCOUNT,0,0
  26.         or      eax,eax
  27.         jz      exit_process
  28.  
  29.         ; Сохранить количество иконок в трее
  30.         mov     [IconsCount],eax
  31.  
  32.         ; Получить ID процесса-владельца трея
  33.         invoke  GetWindowThreadProcessId,[hToolbar],ProcId
  34.         ; Открыть процесс с для чтения и записи
  35.         invoke  OpenProcess,PROCESS_VM_OPERATION or PROCESS_VM_READ,\
  36.                 FALSE,[ProcId]
  37.         or      eax,eax
  38.         ; Фокус не удался
  39.         jz      exit_process
  40.  
  41.         ; Сохранить хэндл процесса-владельца трея
  42.         mov     [hProcess],eax
  43.  
  44.         ; Выделить блок памяти в контексте процесса
  45.         invoke  VirtualAllocEx,[hProcess],NULL,dword sizeof.TBBUTTON,\
  46.                 MEM_COMMIT,PAGE_READWRITE
  47.         or      eax,eax
  48.         jz      exit_process
  49.  
  50.         ; Сохранить указатель на блок памяти
  51.         mov     [lpData],eax
  52.  
  53.         ; Перебрать все иконки в трее
  54. loc_loop:
  55.         ; Все иконки обработали?
  56.         cmp     [IconsCount],0
  57.         je      clear_memory
  58.  
  59.         ; Следующая иконка
  60.         dec     [IconsCount]
  61.  
  62.         ; Получить иконку из трея с индексом IconsCount
  63.         invoke  SendMessage,[hToolbar],TB_GETBUTTON,[IconsCount],[lpData]
  64.         ; Прочитать структуру иконки
  65.         invoke  ReadProcessMemory,[hProcess],[lpData],button,\
  66.                 dword sizeof.TBBUTTON,BytesRead
  67.         or      eax,eax
  68.         jz      clear_memory
  69.         ; Прочиталась вся структура?
  70.         cmp     [BytesRead],sizeof.TBBUTTON
  71.         jnz     clear_memory
  72.  
  73.         ; Прочитать пользовательские данные иконки
  74.         invoke  ReadProcessMemory,[hProcess],[button.dwData],extra,\
  75.                 dword sizeof.EXTRADATA,BytesRead
  76.         or      eax,eax
  77.         jz      clear_memory
  78.         ; Прочиталась вся структура?
  79.         cmp     [BytesRead],sizeof.EXTRADATA
  80.         jnz     clear_memory
  81.  
  82.         ; Это скрытая иконка?
  83.         mov     eax,[extra.uID]
  84.         and     eax,80000000h
  85.         or      eax,eax
  86.         ; Да, пропустить
  87.         jnz     loc_loop
  88.  
  89.         ; Окно процесса существует?
  90.         invoke  IsWindow,[extra.Wnd]
  91.         or      eax,eax
  92.         jnz     loc_loop
  93.  
  94.         ; Удалить иконку, у которой нет родителя
  95.         mov     [nid.cbSize],sizeof.NOTIFYICONDATA
  96.         mov     eax,[extra.Wnd]
  97.         mov     [nid.hWnd],eax
  98.         mov     eax,[extra.uID]
  99.         mov     [nid.uID],eax
  100.         invoke  Shell_NotifyIcon,NIM_DELETE,nid
  101.         jmp     loc_loop
  102.  
  103. clear_memory:
  104.         ; Очистить память и ресурсы
  105.         invoke  VirtualFreeEx,[hProcess],[lpData],0,MEM_RELEASE
  106.         invoke  CloseHandle,[hProcess]
  107.  
  108. exit_process:
Способ простой, надежный и не вызывает побочных эффектов типа реакции приложений при эмуляции движения курсора над треем.

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

Как поменять стандартную иконку любой папки Windows

20.10.2013 | Категория: Software | Автор: ManHunter

Папки с измененными иконками

В Windows есть возможность поменять стандартную иконку папки на любую другую. Это бывает удобно, когда папок много и надо выделить некоторые для более быстрого визуального поиска, или если старые значки вам уже надоели. Еще некоторые приложения любят менять значки на папках, в которые они установлены. Информация о том, как поменять иконку, не является каким-то секретом, кое-кто даже налепил для этого целые многомегабайтные программы, причем некоторые из них даже платные. А вот вам и моя инструкция для новичков и продвинутых пользователей.

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

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