Что нового

Как отобразить иконку файла просто в окне а не в ListView под его расширение

assch

Новичок
Сообщения
166
Репутация
4
Код:
#Include <GUIListView.au3>
#Include <GUIImageList.au3>
#Include <WinAPIEx.au3>

Global $put = "WinAPIEx.chm"

$hForm = GUICreate('MyGUI', 280, 391)

$ListView = GUICtrlCreateListView('', 10, 10, 260, 344, BitOR($LVS_DEFAULT, $LVS_NOCOLUMNHEADER), $WS_EX_CLIENTEDGE)
_GUICtrlListView_SetExtendedListViewStyle($ListView, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_INFOTIP))
_GUICtrlListView_InsertColumn($ListView, 0, '', 234)
$hImageList = _GUIImageList_Create(16, 16, 6)
_GUICtrlListView_SetImageList($ListView, $hImageList, 1)
$Button = GUICtrlCreateButton('OK', 105, 361, 70, 23)

$hIcon = _WinAPI_ShellExtractAssociatedIcon($put, 1)
_GUIImageList_ReplaceIcon($hImageList, -1, $hIcon)
_GUICtrlListView_AddItem($ListView, $put)
_WinAPI_DestroyIcon($hIcon)

GUISetState()

While 1
	$Msg = GUIGetMsg()
	Switch $Msg
		Case -3, $Button
			ExitLoop
	EndSwitch
WEnd

Этот пример кода (немного упрощённый для наглядности) взят из папки Examples библиотеки WinAPIEx.au3 (большое спасибо автору за отличную библиотеку)
В данном случае (для примера) файл "WinAPIEx.chm" отображается в окне. То есть отображается иконка которая забита в системе под его расширение
(в данном случае расширение .chm) ,но она отображается в ListView А как сделать так чтобы она отображалась в окне не в ListView а как обычная иконка
то есть функцией GUICtrlCreateIcon()

Попытался по шаманить но связка
Код:
$hIcon = _WinAPI_ShellExtractAssociatedIcon($put , 1)
GUICtrlCreateIcon($hIcon,0, 50, 50, 32, 32)


к сожелению не работает
Не подскажете как правильно сделать?
 

VladUs

Скриптер
Сообщения
621
Репутация
181
Посмотри пример _WinAPI_ShellExtractIcon () из той же библиотеки
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Там иконки берутся просто из библиотеки
А мне нужно чтобы иконка бралась именно по расширению файла
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Код:
#Include <Constants.au3>
#Include <WinAPIEx.au3>

Global Const $STM_SETIMAGE = 0x0172

GUICreate('MyGUI', 128, 128)
GUICtrlCreateIcon('', 0, 48, 48, 32, 32)
$hIcon = _WinAPI_ShellExtractAssociatedIcon('.chm')
GUICtrlSendMsg(-1, $STM_SETIMAGE, $IMAGE_ICON, $hIcon)
GUISetState()

Do
Until GUIGetMsg() = -3
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Спасибо Yashied
Только к сожелению иконки отображаются чуть чуть не корректно (например нельзя изменить размер иконок)
Кстати я нашёл твой пример на похожую тематику но он работает только с папками а с файлами почему то не хочет




Код:
Global Const $SHGFI_ICONLOCATION = 0x00001000
Global Const $tagSHFILEINFO = 'ptr hIcon;int iIcon;dword Attributes;wchar DisplayName[260];wchar TypeName[80];'

$Path = @FavoritesDir

$tSHFILEINFO = DllStructCreate($tagSHFILEINFO)
_WinAPI_ShellGetFileInfo($Path, $SHGFI_ICONLOCATION, 0, $tSHFILEINFO)
$Icon = DllStructGetData($tSHFILEINFO, 'DisplayName')
$Index = DllStructGetData($tSHFILEINFO, 'iIcon')

GUICreate('MyGUI', 200, 200)
GUICtrlCreateIcon($Icon, -($Index + ($Index > -1)), 50, 50, 32, 32)
GUISetState()

Do
Until GUIGetMsg() = -3


Func _WinAPI_ShellGetFileInfo($sPath, $iFlags, $iAttributes, ByRef $tSHFILEINFO)

    Local $Ret = DllCall('shell32.dll', 'dword_ptr', 'SHGetFileInfoW', 'wstr', $sPath, 'dword', $iAttributes, 'ptr', DllStructGetPtr($tSHFILEINFO), 'uint', DllStructGetSize($tSHFILEINFO), 'uint', $iFlags)

    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[0]
EndFunc
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
В принципи задача стоит вытащить эту иконку в формате .ico (например на рабочий стол)
Ну и соответственно чтобы она была точно такого же качества как и иконка файла.
(для сравнения лучше использовать Рабочий стол так как на рабочем столе лучше просматривать иконки)

Можно например с помощью этого кода отловить запись в реестре по поводу "DefaultIcon"
Код:
$Key = RegRead('HKCR\.aca', '')
$CLSID = RegRead('HKCR\' & $Key & '\CLSID', '')
If $CLSID Then
    $Icon = RegRead('HKCR\CLSID\' & $CLSID & '\DefaultIcon', '')
Else
    $Icon = RegRead('HKCR\' & $Key & '\DefaultIcon', '')
EndIf
MsgBox(32,0,$Icon & @CR)


но этот код у меня почему то не отловил записи по расширению ".aca"
Но зато другой код отловил эту запись по расширению ".aca"
Код:
MsgBox(32,0,RegRead('HKCR\' & RegRead('HKCR\.aca', '') & '\DefaultIcon', '') & @CR)


Но к сожелению ни тот ни другой (у меня) не отловили расширение ".386"
Ещё раз повторюсь что пример из библиотеки "WinAPIEx_3.2" "_WinAPI_ShellExtractAssociatedIcon.au3"
Справилась с задачей не могу точно утверждать но на первый взгляд без проблем
Все расширения заполнены соответствующими иконками (если правда соответствующий файл с иконками находится на месте а то иногда бывает
что пути прописаны а файла на месте нет но я так понял если файла нет то система ставит свою иконку по умолчанию) Функция справилась
хорошо в том числе и с расширением ".386"

Но вот как любую из этих иконок в нормальном качестве вытащить (например на рабочий стол) в формате ".ico" ???????
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
assch

Для начала, разберись, что именно тебе нужно. Для отображения ассоциированных иконок в GUI более, чем достаточно, одной из следующих функций:

_WinAPI_ShellExtractAssociatedIcon()
_WinAPI_AssocQueryString()

Первая возвращает указатель (хендл), что проще, быстрее и правильнее, вторая - путь к файлу, содержащему иконку, и индекс иконки внутри файла. И обе эти функции прекрасно работают (см. File Types Manager в качестве примера).

Сохранение иконки, а по сути "указателя", в .ico файл, это отдельная песня, ну, и соответственно отдельная тема. Если будет время напишу...

assch сказал(а):
Код:
$Key = RegRead('HKCR\.aca', '')
$CLSID = RegRead('HKCR\' & $Key & '\CLSID', '')
If $CLSID Then
    $Icon = RegRead('HKCR\CLSID\' & $CLSID & '\DefaultIcon', '')
Else
    $Icon = RegRead('HKCR\' & $Key & '\DefaultIcon', '')
EndIf
MsgBox(32,0,$Icon & @CR)

Это неверный подход, т.к. иконки могут находиться не только в этих местах реестра.
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
В своё время я поднимал тему с иконками и с вашей помощью я сделал утилитку (так ради интереса) которая
заменяет иконки у папок которые находит в некоторых ресурсах Но а сейчас просто хочу увеличить круг поиска
этих иконок

Если кому интересно ссылка на утилитку
http://narod.ru/disk/8140778001/Stilist.rar.html
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Задача одна
Вытащить иконки в формате .ico
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
assch сказал(а):
Задача одна
Вытащить иконки в формате .ico

Я же сказал, отдельная тема.

P.S

А зачем нужно сохранять иконку в файл?
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Чтобы потом запихнуть её в папку и папка примет её вид
Я же писал это просто (лишняя фишка к моей программе)
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Yashied Подскажи пожалуйста почему этот код отлавливает пути к иконкам только для папок а для файлов не работает
Ведь если бы он работал и с файлами также как и с папками то тогда бы не было
ни каких проблем




Код:
Global Const $SHGFI_ICONLOCATION = 0x00001000
Global Const $tagSHFILEINFO = 'ptr hIcon;int iIcon;dword Attributes;wchar DisplayName[260];wchar TypeName[80];'

$Path = @FavoritesDir

$tSHFILEINFO = DllStructCreate($tagSHFILEINFO)
_WinAPI_ShellGetFileInfo($Path, $SHGFI_ICONLOCATION, 0, $tSHFILEINFO)
$Icon = DllStructGetData($tSHFILEINFO, 'DisplayName')
$Index = DllStructGetData($tSHFILEINFO, 'iIcon')

MsgBox(32,0,$Icon)

GUICreate('MyGUI', 200, 200)
GUICtrlCreateIcon($Icon, -($Index + ($Index > -1)), 50, 50, 32, 32)
GUISetState()

Do
Until GUIGetMsg() = -3


Func _WinAPI_ShellGetFileInfo($sPath, $iFlags, $iAttributes, ByRef $tSHFILEINFO)

    Local $Ret = DllCall('shell32.dll', 'dword_ptr', 'SHGetFileInfoW', 'wstr', $sPath, 'dword', $iAttributes, 'ptr', DllStructGetPtr($tSHFILEINFO), 'uint', DllStructGetSize($tSHFILEINFO), 'uint', $iFlags)

    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[0]
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Спроси об этом у Microsoft, я это уже давно заметил. Ты можешь использовать _WinAPI_AssocQueryString().

Код:
#Include <WinAPIEx.au3>

$sIcon = _WinAPI_AssocQueryString('.au3', $ASSOCSTR_DEFAULTICON)
$aIcon = _WinAPI_PathParseIconLocation($sIcon)
If Not @error Then
	ConsoleWrite('Path:  ' & _WinAPI_PathUnquoteSpaces($aIcon[0]) & @CR)
	ConsoleWrite('Index: ' & $aIcon[1] & @CR)
EndIf


А для установления иконки (и не только) для папки, я рекомендую использовать _WinAPI_ShellGetSetFolderCustomSettings(), там есть пример.
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Большое спасибо Yashied
Кажется то что нужно
Буду тестировать
 
Верх