Что нового

Не корректное копирование иконки

Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Yashied
Как ты считаешь а если по шаманить.
Например создавать пустой файл с этим рассширением например на рабочем столе (система ведь сама сделает эту иконку)
Ну а потом как то вытащить этот образ иконки.
Это как версия (не исключено что это утопия)
Но ведь функция "_WinAPI_ShellExtractAssociatedIcon" показывает иконки правильно и она откуда то берёт эти образы иконок.
 

Yashied

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

Global $aaa = 'blg'
Global $bbb = '.' & $aaa

$GUI = GUICreate($aaa, 400, 270, 100, 250)

#Region Yashied

Dim $aIcon[2]
For $i = 0 To 1
	$aIcon[$i] = _WinAPI_ShellExtractAssociatedIcon($bbb, $i)
Next
_WinAPI_SaveHICONToFile($aaa & '.ico', $aIcon)
For $i = 0 To 1
	_WinAPI_DestroyIcon($aIcon[$i])
Next

#EndRegion Yashied

;GUICtrlCreateLabel("Путь:   " & $put, 10, 150, 380, 40)
;GUICtrlCreateLabel("Индекс: " & $ind, 10, 190, 380, 20)

$sfrien = _WinAPI_AssocQueryString($bbb, $ASSOCSTR_FRIENDLYDOCNAME)
GUICtrlCreateLabel($sfrien, 10, 230, 380, 20)

;GUICtrlCreateIcon($put, _Index($ind), 100, 50, 48, 48)

GUICtrlCreateIcon($aaa & ".ico", 0, 250, 50, 48, 48)

GUISetState()

While 1
	$iMsg = GUIGetMsg()
	Switch $iMsg

		Case -3
			FileDelete($bbb)
			FileDelete($aaa & ".ico")
			Exit

	EndSwitch
WEnd


P.S

А для чего нужно вот это?

Код:
FileOpen($bbb,2)
 
Автор
A

assch

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

assch

Новичок
Сообщения
166
Репутация
4
Yashied [?]
А для чего нужно вот это?
Код:
FileOpen($bbb,2)


Это я просто для наглядности чтобы посмотреть какие иконки для данного расширения
создаёт сама система.

Я его потом уберу.

Не большое наблюдение
Если системно создать пустой файл ".blg" на рабочем столе и нашем кодом положить туда рядом иконку
то видно что наша иконка чуть чуть размыта особенно это видно по загнутому уголку .
То есть файл "blg.ico" получается чуть чуть размытым чем иконка файла ".blg" созданная самой системой.
Можно это подкорректировать?
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
В полной мере я не тестировал но в принципи должно работать.
Функцию "_WinAPI_ShellExtractAssociatedIcon" пришлось назвать "_WinAPI_ShellExtractAssociatedIcon_2"
(чтобы не вступала в конфликт с библиотекой "WinAPIEx")
В этой функции для функции "_WinAPI_ShellGetFileInfo" методом проб добавил флаги "$SHGFI_LARGEICON + $SHGFI_SHELLICONSIZE"
Как результат иконка стала выводится более чёткая (такая же как и система показывает её на рабочем столе)

Особенная благодарность нашему Глобальному модератору Yashied
за отличную помощь и поддержку :IL_AutoIt_1:
Код:
#Include <WinAPIEx.au3>

Global $aaa = 'blg'
Global $bbb = '.' & $aaa
FileOpen($bbb,2)
$GUI = GUICreate($bbb, 300, 180, 100, 250)

#Region Yashied

Dim $aIcon[2]
For $i = 0 To 1
    $aIcon[$i] = _WinAPI_ShellExtractAssociatedIcon_2($bbb, $i)
Next
_WinAPI_SaveHICONToFile($aaa & '.ico', $aIcon)
For $i = 0 To 1
    _WinAPI_DestroyIcon($aIcon[$i])
Next

#EndRegion Yashied

$sfrien = _WinAPI_AssocQueryString($bbb, $ASSOCSTR_FRIENDLYDOCNAME)
GUICtrlCreateLabel($sfrien, 20, 130, 380, 20)
GUICtrlCreateIcon($aaa & ".ico", 0, 20, 40, 48, 48)

GUISetState()

While 1
    $iMsg = GUIGetMsg()
    Switch $iMsg

        Case -3
            FileDelete($bbb)
            FileDelete($aaa & ".ico")
            Exit

    EndSwitch
WEnd



Func _WinAPI_ShellExtractAssociatedIcon_2($sFile, $fSmall = 0)

	Local $Flags = $SHGFI_ICON+ $SHGFI_LARGEICON + $SHGFI_SHELLICONSIZE + $SHGFI_USEFILEATTRIBUTES

	Local $tSHFILEINFO = DllStructCreate($tagSHFILEINFO)

	If Not _WinAPI_ShellGetFileInfo($sFile, $Flags, 0, $tSHFILEINFO) Then
		Return SetError(1, 0, 0)
	EndIf
	Return DllStructGetData($tSHFILEINFO, 'hIcon')
EndFunc



Func _WinAPI_SaveHICONToFile($sFile, $aIcon, $iStart = 0, $iEnd = -1)

    Local $Icon, $Count = 1

    If IsArray($aIcon) Then
        If UBound($aIcon, 2) Then
            Return SetError(2, 0, 0)
        EndIf
        If $iStart < 0 Then
            $iStart = 0
        EndIf
        If ($iEnd < 0) Or ($iEnd > UBound($aIcon) - 1) Then
            $iEnd = UBound($aIcon) - 1
        EndIf
        $Count = $iEnd - $iStart + 1
        If $Count < 1 Then
            Return SetError(1, 0, 0)
        EndIf
        Dim $Icon[$Count]
        For $i = 0 To $Count - 1
            $Icon[$i] = $aIcon[$iStart + $i]
        Next
    Else
        Dim $Icon[1] = [$aIcon]
    EndIf

    Local $hFile = _WinAPI_CreateFileEx($sFile, 2, 0x40000000, 0)

    If @error Then
        Return SetError(1, 0, 0)
    EndIf

    Local $tData, $W, $H, $Info, $Bytes, $Error, $Result = 0
    Local $tIco = DllStructCreate('ushort Reserved;ushort Type;ushort Count;byte Data[' & (16 * $Count) & ']')
    Local $Lenght = DllStructGetSize($tIco)
    Local $pIco = DllStructGetPtr($tIco)
    Local $tBI = DllStructCreate($tagBITMAPINFOHEADER)
    Local $pBI = DllStructGetPtr($tBI)
    Local $tDIB = DllStructCreate($tagDIBSECTION)
    Local $Size = DllStructGetSize($tDIB)
    Local $pDIB = DllStructGetPtr($tDIB)
    Local $Offset = $Lenght

    DllStructSetData($tIco, 'Reserved', 0)
    DllStructSetData($tIco, 'Type', 1)
    DllStructSetData($tIco, 'Count', $Count)

    DllStructSetData($tBI, 'biSize', 40)
    DllStructSetData($tBI, 'biPlanes', 1)
    DllStructSetData($tBI, 'biBitCount', 32)
    DllStructSetData($tBI, 'biCompression', 0)
    DllStructSetData($tBI, 'biXPelsPerMeter', 0)
    DllStructSetData($tBI, 'biYPelsPerMeter', 0)
    DllStructSetData($tBI, 'biClrUsed', 0)
    DllStructSetData($tBI, 'biClrImportant', 0)

    Do
        If Not _WinAPI_WriteFile($hFile, $pIco, $Lenght, $Bytes) Then
            ExitLoop
        EndIf
        For $i = 0 To $Count - 1
            $Info = _WinAPI_GetIconInfo($Icon[$i])
            If Not IsArray($Info) Then
                ExitLoop 2
            EndIf
            For $j = 4 To 5
                $Info[$j] = _WinAPI_CopyImage($Info[$j], 0, 0, 0, BitOR(0x2000, 0x0008))
                If _WinAPI_GetObject($Info[$j], $Size, $pDIB) Then
                    $Info[$j - 4] = DllStructGetData($tDIB, 'biSizeImage')
                    $Info[$j - 2] = DllStructGetData($tDIB, 'bmBits')
                Else
                    $Info[$j - 4] = 0
                    $Info[$j - 2] = 0
                EndIf
            Next
            $W = DllStructGetData($tDIB, 'bmWidth')
            $H = DllStructGetData($tDIB, 'bmHeight')
            $tData = DllStructCreate('byte Width;byte Height;byte Colors;byte Reserved;word Planes;word BPP;long Size;long Offset', $pIco + 6 + 16 * $i)
            DllStructSetData($tData, 'Width', $W)
            DllStructSetData($tData, 'Height', $H)
            DllStructSetData($tData, 'Colors', 0)
            DllStructSetData($tData, 'Reserved', 0)
            DllStructSetData($tData, 'Planes', 1)
            DllStructSetData($tData, 'BPP', 32)
            DllStructSetData($tData, 'Size', 48 + $Info[0] + $Info[1])
            DllStructSetData($tData, 'Offset', $Offset)
            DllStructSetData($tBI, 'biWidth', $W)
            DllStructSetData($tBI, 'biHeight', 2 * $H)
            DllStructSetData($tBI, 'biSizeImage', $Info[0] + $Info[1])
            $Offset += 40 + $Info[0] + $Info[1]
            Do
                $Error = 1
                If Not _WinAPI_WriteFile($hFile, $pBI, 40, $Bytes) Then
                    ExitLoop
                EndIf
                For $j = 1 To 0 Step -1
                    If Not _WinAPI_WriteFile($hFile, $Info[$j + 2], $Info[$j], $Bytes) Then
                        ExitLoop 2
                    EndIf
                Next
                $Error = 0
            Until 1
            For $j = 4 To 5
                _WinAPI_DeleteObject($Info[$j])
            Next
            If $Error Then
                ExitLoop 2
            EndIf
        Next
        _WinAPI_SetFilePointer($hFile, 0)
        If Not _WinAPI_WriteFile($hFile, $pIco, $Lenght, $Bytes) Then
            ExitLoop
        EndIf
        $Result = 1
    Until 1
    _WinAPI_CloseHandle($hFile)
    If Not $Result Then
        FileDelete($sFile)
    EndIf
    Return SetError(Number(Not $Result), 0, $Result)
EndFunc

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_SaveHICONToFile
; Description....: Saves a 32 bits-per-pixel single or multiple icon (HICON) to the specified icon (.ico) file.
; Syntax.........: _WinAPI_SaveHICONToFile ( $sFile, $aIcon [, $iStart [, $iEnd]] )
; Parameters.....: $sFile  - The name of the icon file.
;                  $aIcon  - Handle to the icon or array of the icon handles to be save.
;                  $iStart - The index of array to start saving at.
;                  $iEnd   - The index of array to stop saving at.
; Return values..: Success - 1.
;                  Failure - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......:
; Remarks........: This function only works with 32 bits-per-pixel (RGB + Alpha) icons. If you do not know exactly which color
;                  depth is there an icon, use the _WinAPI_Create32BitHICON() function to convert its.
; Related........:
; Link...........: None
; Example........: Yes
; ===============================================================================================================================
 
Верх