Что нового

Иконка из заголовка чужого приложения

Astel064

Помог мой пост, ставь +!
Сообщения
276
Репутация
51
Здравствуйте.
Каким образом можно получить путь и индекс иконки, которую использует любое приложение в своем окне?
Имею в виду ту иконку, которая в левом верхнем углу окон приложений...
 

Вложения

  • 2014-09-13_030717.jpg
    2014-09-13_030717.jpg
    53.9 КБ · Просмотры: 24
  • 2014-09-13_030902.jpg
    2014-09-13_030902.jpg
    22.5 КБ · Просмотры: 24

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Обычно иконка окна бывает той же что и иконка самого приложения - то можно брать из ресурсов.
Но иногда программа сама может заменить свою иконку из двоичных ресурсов
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Если я думаю то же, что и ты, то вот:
Установить иконку своего окна чужому (калькулятору).

Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

$frmMain = GUICreate("Form1", 364, 164, 192, 114)
$btn = GUICtrlCreateButton("Button1", 104, 48, 75, 25)
GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $btn
			local $res = _WinAPI_GetModuleHandle(0)
			if $res Then
				$res = _WinAPI_LoadImage($res,99,$IMAGE_ICON,0,0,$LR_DEFAULTSIZE) ; 99 - ординал иконки в exe
				if $res then
					_WinAPI_PostMessage(WinGetHandle("Калькулятор"),$WM_SETICON,1,$res)
				EndIf
			EndIf
	EndSwitch
WEnd


aeazjz.png
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Astel064,
Если Я Вас правильно понял, то можно сделать примерно так.
Код:
#include <WinAPIEX.au3>
#include <GUIConstantsEx.au3>

Global $hCalc, $hIcon, $hIconCopy, $aInfo, $tSize, $iW, $iH

$hCalc = WinGetHandle('[Class:CalcFrame]')
If Not $hCalc Then
	Run('calc.exe')
	$hCalc = WinWait('[Class:CalcFrame]', '', 3)
EndIf
If Not $hCalc Then Exit 1
$hIcon = _WinAPI_GetClassLongEx($hCalc, -14);$GCL_HICON = -14
If Not $hIcon Then Exit 2
$hIconCopy = _WinAPI_CopyIcon($hIcon)
_WinAPI_DestroyIcon($hIcon)
If Not $hIconCopy Then Exit 3
$aInfo = _WinAPI_GetIconInfo($hIconCopy)
If @error Then Exit 4
$tSize = _WinAPI_GetBitmapDimension($aInfo[5])
$iW = DllStructGetData($tSize, 1)
$iH = DllStructGetData($tSize, 2)
If Not $iW Then $iW = 32
If Not $iH Then $iH = 32
For $i = 4 To 5
	_WinAPI_DeleteObject($aInfo[$i])
Next
$aInfo = 0
$tSize = 0
GUICreate('Test', $iW * 5, $iH * 3)
GUICtrlCreateIcon('', 0, $iW * 2, $iH, $iW, $iH)
GUICtrlSendMsg(-1, 0x0172, 1, $hIconCopy);$STM_SETIMAGE = 0x0172
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
_WinAPI_DestroyIcon($hIconCopy)
 
Автор
Astel064

Astel064

Помог мой пост, ставь +!
Сообщения
276
Репутация
51
Спасибо madmasles, это почти то, что нужно!
Такой к Вам вопрос: а если приложение установило себе иконку не из своего файла, а например, из "shell32.dll"?
И возможно-ли получить путь и индекс используемой иконки (или сохранить ее как отдельный файл)?
 
Автор
Astel064

Astel064

Помог мой пост, ставь +!
Сообщения
276
Репутация
51
madmasles [?]
Можно сохранить функцией _WinAPI_SaveHICONToFile().
И снова спасибо, снова то, что нужно!

Но вот что делать, если приложение использует в заголовке своего окна другую (не свою) иконку? Например, взятую из Explorer.exe, 1?
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Astel064 [?]
Но вот что делать, если приложение использует в заголовке своего окна другую (не свою) иконку? Например, взятую из Explorer.exe, 1?
Абсолютно так же, ведь по сути вы работаете всего лишь с дескриптором иконки, который уникален.
 
Автор
Astel064

Astel064

Помог мой пост, ставь +!
Сообщения
276
Репутация
51
oesoes [?]
Абсолютно так же, ведь по сути вы работаете всего лишь с дескриптором иконки, который уникален.
С дескриптором иконки файла, а не окна

madmasles [?]
Смотрите пример к функции _WinAPI_GetIconInfoEx().
Посмотрел, ничего нужного не нашел в примере

У меня собрался следующий скрипт (№1) (на основе скрипта madmasles)
Код:
#include <WinAPIEX.au3>
;#include <apiconstants.au3>
#include <GUIConstantsEx.au3>

Global $hWnd, $hIcon, $hIconCopy, $aInfo, $tSize, $iW, $iH

$hWnd = WinGetHandle('[TITLE:Form1]')
	If Not $hWnd Then Exit 1

$hIcon = _WinAPI_GetClassLongEx($hWnd, -14);$GCL_HICON = -14
	If Not $hIcon Then Exit 2

$hIconCopy = _WinAPI_CopyIcon($hIcon)
_WinAPI_DestroyIcon($hIcon)
	If Not $hIconCopy Then Exit 3

$aInfo = _WinAPI_GetIconInfo($hIconCopy)
	If @error Then Exit 4

$tSize = _WinAPI_GetBitmapDimension($aInfo[5])
$iW = DllStructGetData($tSize, 1)
$iH = DllStructGetData($tSize, 2)
	If Not $iW Then $iW = 32
	If Not $iH Then $iH = 32

For $i = 4 To 5
    _WinAPI_DeleteObject($aInfo[$i])
Next

$aInfo = 0
$tSize = 0

GUICreate('Test', $iW * 5, $iH * 3)
GUICtrlCreateIcon('', 0, $iW * 2, $iH, $iW, $iH)
GUICtrlSendMsg(-1, 0x0172, 1, $hIconCopy);$STM_SETIMAGE = 0x0172
_WinAPI_SaveHICONToFile ( @ScriptDir&"\000.ico", $hIconCopy )
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
_WinAPI_DestroyIcon($hIconCopy)


А этот скрипт (№2) создает окно со значком от explorer.exe, 1 и первый скрипт (вроде как) должен сохранить этот значок в @ScriptDir&"\000.ico"
Код:
#Notrayicon
#AutoIt3Wrapper_Icon=Icon.ico
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("Form1", 623, 443, 192, 124)
	GUISetIcon ( "Explorer.exe", 1 )
GUISetState(@SW_SHOW)
While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd


Но вся проблема в том, что скрипт №1 сохраняет иконку, которая находится в ресурсах скрипта №2, а не ту, что установлена в заголовке окна скрипта №2 (explorer.exe, 1)...
Помогите, пожалуйста, сделать, чтобы скрипт №1 сохранял именно ту иконку, которая стоит в заголовке скрипта №2, а не ту, что в ресурсах...
 

Вложения

  • Наработки.zip
    6.7 КБ · Просмотры: 4

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Astel064 [?]
С дескриптором иконки файла, а не окна
Я про окно ничего и не говорил ;) Я про то, что нет разницы, свою иконку софт использует, или не свою - по барабану. На месте хендла будет хендл, а там уже пофик хендл чьей иконки там сидит.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Astel064 [?]
ничего нужного не нашел в примере
А так?
Код:
#include <WinAPIEX.au3>
#include <GUIConstantsEx.au3>

If _WinAPI_GetVersion() < '6.0' Then
	MsgBox(16, 'Error', 'Require Windows Vista or later.')
	Exit
EndIf

Global $hCalc, $hIcon, $aInfo

$hCalc = WinGetHandle('[Class:CalcFrame]')
If Not $hCalc Then
	Run('calc.exe')
	$hCalc = WinWait('[Class:CalcFrame]', '', 3)
EndIf
If Not $hCalc Then Exit 1
$hIcon = _WinAPI_GetClassLongEx($hCalc, -14);$GCL_HICON = -14
If Not $hIcon Then Exit 2
$aInfo = _WinAPI_GetIconInfoEx($hIcon)
If Not @error Then
	ConsoleWrite('Path:   ' & $aInfo[6] & @CR)
	ConsoleWrite('ID:     ' & $aInfo[5] & @CR)
	For $i = 3 To 4
		_WinAPI_DeleteObject($aInfo[$i])
	Next

	GUICreate('Test', 200, 200)
	GUICtrlCreateIcon($aInfo[6], $aInfo[5], 30, 30)
	GUISetState()

	Do
	Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndIf
_WinAPI_DestroyIcon($hIcon)
 
Верх