Быстрый поиск
Введите фрагмент названия статьи для поиска
Как узнать название шрифта в диалоговом окне приложения
14.03.2013 | Категория: Образ мышления: Assembler | Автор: ManHunter
Для того, чтобы получить информацию о шрифте, используемом в окне или его отдельном элементе, можно применить следующий код.Code (Assembler) : Убрать нумерацию
- ; Отправить окну запрос на получение информации о шрифте
- invoke SendMessage,[hWindow],WM_GETFONT,NULL,NULL
- or eax,eax
- ; Данные о шрифте получить не удалось
- jz cant_get_font
- ; Получить объект с описанием шрифта
- invoke GetObject,eax,sizeof.LOGFONT,font
- ; Теперь в font.lfFaceName строка названия шрифта
Читать статью целиком »
Просмотров: 9483 | Комментариев: 7
Получение иконки из окна чужого приложения
23.07.2012 | Категория: Образ мышления: Assembler | Автор: ManHunter
В некоторых приложениях, например, в различных таскменеджерах, возникает задача получить иконку окна другого приложения, чтобы затем использовать ее в своем контексте. Делается это очень просто. Окну посылается сообщение WM_GETICON с параметром ICON_SMALL или ICON_BIG, в зависимости от того, маленькую или большую иконку надо получить. Если это не срабатывает, то можно попробовать получить иконку при помощи функции GetClassLong, соответственно, с параметром GCL_HICONSM или GCL_HICON. Если и в этом случае хэндл иконки получить не удалось, то значит не судьба. Или приложение, которому принадлежит окно, не отвечает, или же окно просто не имеет иконки. Для облегчения задачи я написал следующую функцию:Code (Assembler) : Убрать нумерацию
- ;--------------------------------------------------------------
- ; Функция получения иконки окна
- ; by ManHunter / PCL
- ; http://www.manhunter.ru
- ;--------------------------------------------------------------
- ; Параметры:
- ; hwnd - хэндл окна
- ; dType - тип иконки (0 - 16x16, 1 - 32x32)
- ; На выходе:
- ; EAX - хэндл иконки или -1 если окна не существует
- ;--------------------------------------------------------------
- proc GetIcon hwnd:DWORD, dType:DWORD
- pusha
- ; Такое окно существует?
- invoke IsWindow,[hwnd]
- or eax,eax
- jnz @f
- ; Окно не найдено
- mov eax,-1
- jmp .loc_ret
- @@:
- ; Какую иконку надо получить?
- cmp [dType],0
- jne .get_big_icon
- ; Получить хэндл маленькой иконки
- .get_small_icon:
- invoke SendMessage,[hwnd],WM_GETICON,ICON_SMALL,0
- or eax,eax
- jnz .loc_ret
- invoke GetClassLong,[hwnd],GCL_HICONSM
- or eax,eax
- jnz .loc_ret
- jmp .load_def
- ; Получить хэндл большой иконки
- .get_big_icon:
- invoke SendMessage,[hwnd],WM_GETICON,ICON_BIG,0
- or eax,eax
- jnz .loc_ret
- invoke GetClassLong,[hwnd],GCL_HICON
- or eax,eax
- jnz .loc_ret
- ; Получить хэндл иконки по умолчанию
- .load_def:
- invoke LoadIcon,NULL,IDI_WINLOGO
- .loc_ret:
- mov [dType],eax
- popa
- ; Вернуть результат
- mov eax,[dType]
- ret
- endp
Читать статью целиком »
Просмотров: 4900 | Комментариев: 3
Принудительное обновление иконок в трее
12.01.2012 | Категория: Образ мышления: Assembler | Автор: ManHunter
В случае аварийного завершения или некорректной работы некоторых приложений, в системном трее могут оставаться "мертвые" иконки, которые уже не принадлежат ни одному запущенному процессу. Глюк хоть и не смертельный, но все равно неприятный. И основная проблема в том, что область трея никак не реагирует на внешние сообщения типа WM_REPAINT, и функции типа UpdateWindow и InvalidateRect. То есть автоматически обновить или перерисовать его, чтобы избавиться от "мертвых" иконок, не получится. Но такие иконки удаляются, если провести курсором мышки над ними. Значит единственный способ перерисовать иконки в трее - это сэмулировать движение мыши над окном трея. Как найти окно трея и его хэндл мы уже знаем, тут ничего нового. В сегменте данных те же значения:Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- class1 db 'Shell_TrayWnd',0 ; Название класса окна трея
- class2 db 'TrayNotifyWnd',0 ; Название класса панели уведомлений
- class3 db 'SysPager',0 ; Трей
- class4 db 'ToolbarWindow32',0 ; Панель с иконками
- ToolbarHandle dd ? ; Хэндл окна трея
- ToolbarRect RECT ; Размер окна трея
Code (Assembler) : Убрать нумерацию
- ; Найти окно трея
- invoke FindWindow,class1,NULL
- or eax,eax
- jz exit_process
- ; Найти панель уведомлений
- invoke FindWindowEx,eax,NULL,class2,NULL
- or eax,eax
- jz exit_process
- ; Найти трей
- invoke FindWindowEx,eax,NULL,class3,NULL
- or eax,eax
- jz exit_process
- ; Найти панель иконок в трее
- invoke FindWindowEx,eax,NULL,class4,NULL
- or eax,eax
- jz exit_process
- ; Сохранить хэндл окна с иконками
- mov [ToolbarHandle],eax
Читать статью целиком »
Просмотров: 8933 | Комментариев: 21
Как узнать, что программа запущена под Администратором
20.11.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда требуется узнать, запущена ли ваша программа под учетной записью с правами Администратора, или же от обычного пользователя. Для чего это нужно? Например, некоторые операции с реестром или файлами требуют права Администратора. При попытке выполнить их обычному пользователю вернется ошибка ERROR_ACCESS_DENIED, но для более точного анализа ситуации надо будет проверить права доступа и уведомить об этом пользователя. Проверить, что программа запущена под Администратором, можно несколькими способами.Первый способ наиболее универсальный и работает даже на старых операционных системах. Он заключается в том, что надо получить группы доступа для токена текущего процесса, а затем проверить, входит ли хоть одна из них в группу Администраторов локального компьютера. Вот пример реализации:
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- SECURITY_NT_AUTHORITY = 5
- TOKEN_READ = 0x00020008
- SECURITY_BUILTIN_DOMAIN_RID = 0x00000020
- DOMAIN_ALIAS_RID_ADMINS = 0x00000220
- TokenGroups = 0x00000002
- BUFF_SIZE = 1024h ; Размер буфера для групп доступа токена
- NtAuthority db 0,0,0,0,0,SECURITY_NT_AUTHORITY
- hTokenHandle dd ?
- dInfoSize dd ?
- psidAdmins dd ?
- hHeap dd ?
- pTokenGroups dd ?
- ;---------------------------------------------
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Получить токен текущего процесса
- invoke GetCurrentProcess
- invoke OpenProcessToken,eax,TOKEN_READ,hTokenHandle
- ; Выделить память для массива групп
- invoke GetProcessHeap
- mov [hHeap],eax
- invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,BUFF_SIZE
- mov [pTokenGroups],eax
- ; Получить информацию о группах доступа токена
- invoke GetTokenInformation,[hTokenHandle],TokenGroups,\
- [pTokenGroups],dword BUFF_SIZE,dInfoSize
- ; Прибраться за собой
- invoke CloseHandle,[hTokenHandle]
- invoke AllocateAndInitializeSid,NtAuthority,2,\
- SECURITY_BUILTIN_DOMAIN_RID,\
- DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,psidAdmins
- ; Количество записей в структуре TOKEN_GROUPS
- mov esi,[pTokenGroups]
- mov ebx,dword [esi]
- ; Указатель на массив SID_AND_ATTRIBUTES
- add esi,4
- @@:
- ; Проверить соответствие SID
- mov eax,dword [esi]
- invoke EqualSid,[psidAdmins],eax
- or eax,eax
- jnz loc_admin
- ; Следующая группа
- add esi,8
- dec ebx
- or ebx,ebx
- jnz @b
- loc_not_admin:
- ; Пользователь не Администратор
- ...
- loc_admin:
- ; Пользователь Администратор
- ...
Читать статью целиком »
Просмотров: 10576 | Комментариев: 22
Диалог открытия файлов и юзабилити Windows
02.11.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
При всех удобствах Windows некоторые моменты меня очень сильно раздражают. Особенно поведение системы при вызове диалогов открытия файлов. Сперва немного предыстории. При работе с файлами через функцию GetOpenFileName или GetSaveFileName в структуре OPENFILENAME есть возможность указать путь, который должен открыться по умолчанию. Если это значение не задано, то система сама где-то запоминает папку, в которой последний раз был удачно открыт файл (то есть окно выбора файла было закрыто через кнопку "Ok"). Где именно хранится эта информация - я пока не выяснил, да и не особо надо. Второй вариант. Предположим, что некоторая программа самостоятельно запоминает путь к папке, в которой последний раз ею выполнялись какие-то действия с файлами. Это может быть, например, текстовый редактор, просмотрщик графики и т.п., не суть. Главное, что задумка очень хорошая и правильная. При следующем запуске или вызове диалога выбора файла в соответствующее поле OPENFILENAME будет подставлен сохраненный путь и пользователь продолжит работу с того места, где он в прошлый раз остановился. Что-то типа такого:Code (Assembler) : Убрать нумерацию
- ...
- invoke GetModuleHandle,0
- mov [ofn.hInstance],eax
- mov [ofn.lStructSize], sizeof.OPENFILENAME
- mov [ofn.hwndOwner],0
- mov [ofn.nMaxFile],MAX_PATH
- mov [ofn.lpstrFile],buff
- ; Открывать с последней сохраненной папки
- mov [ofn.lpstrInitialDir],saved_dir
- mov [ofn.Flags],OFN_EXPLORER+OFN_FILEMUSTEXIST
- invoke GetOpenFileName,ofn
- ...
Читать статью целиком »
Просмотров: 7293 | Комментариев: 6