Что нового

SIP - Selected Image Preview - Предпросмотр выделенного изображения

Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied [?]
Ладно не важно, уже понравилось ;D.

[?]
Плохо. Теряется вся гибкость утилиты. Проще тогда будет два раза кликнуть и вызвать Windows Preview.
С таким же успехом можно сказать и про нажатие с задержкой. Я думаю как опция это не помешает, хотя реализация видимо будет не из простых.

Если использовать удержание средней кнопки мыши (колеса) вместо ЛКМ, то эта проблема отпадает, т.к. ни переименование, ни Drag-n-Drop не будут работать. Подумай.
Подумаю, но всё таки мне больше нравится ЛКМ.

У меня не висит.
:laugh:
Ты же понимаешь, что мне придётся лично для себя (как минимум) искать решение совместимости двойного нажатия с показом эскиза, потому что отключать эту опцию я не собираюсь.

Ну ты совсем обленился, лень уже два раза нажать.
Дело совсем не в лени. Много лет назад, когда я купил свой первый компьютер, там вместе с мышкой шла утилита, в которой по умолчанию была установлена данная опция, вот с тех времён я и привык, отвыкнуть уже никак, это для меня стало стандартным поведением средней кнопки мышки.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

OffTopic:
Yashied [?]
У меня не висит.
кстати да. у меня тоже средняя кнопка управляется системой. если по ссылке, то новая вкладка. если на странице, то прокрутка вверх-вниз. а для двойного клика у меня есть еще одна кнопка сбоку. но на колесико, честно говоря впервые вижу там двойной кли )))))
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

CreatoR, как тебе такой расклад?

Код:
#Include <APIConstants.au3>
#Include <GDIP.au3>
#Include <WinAPIEx.au3>

Global Const $Min = 128
Global Const $Max = 512

_GDIPlus_Startup()

$hForm = GUICreate('MyGUI', 360, 360, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetState()

$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\Test.png')
$Size = _GDIPlus_ImageGetDimension($hImage)
If Not IsArray($Size) Then
	Exit
EndIf
Dim $K[2] = [1, 1]
For $i = 0 To 1
	If $Size[$i] > $Max Then
		$K[$i] = $Max / $Size[$i]
	EndIf
Next
For $i = 0 To 1
	If $K[1] > $K[0] Then
		$Size[$i] *= $K[0]
	Else
		$Size[$i] *= $K[1]
	EndIf
	If $Size[$i] < $Min Then
		$Size[$i] = $Min
	EndIf
Next

$hPreview = _CreatePreview($hImage, $Size[0] + 36, $Size[1] + 36, 1)
If Not $hPreview Then
	Exit
EndIf

_ShowPreview($hForm, $hPreview, -1, -1, 70, 1)

Do
Until GUIGetMsg() = -3

Func _CreatePreview($hImage, $iWidth, $iHeight, $fDelete = 0)

    Local $aPart[4][5] = [[17, 5, $iWidth - 34, 12, -90], [$iWidth - 17, 17, 12, $iHeight - 34, 0], [17, $iHeight - 17, $iWidth - 34, 12, 90], [5, 17, 12, $iHeight - 34, 180]]
	Local $Size, $tRect, $hGraphics, $hBrush, $hPen, $hPreview
	Local $K[2] = [1, 1]

	$Size = _GDIPlus_ImageGetDimension($hImage)
	If Not IsArray($Size) Then
		Return 0
	EndIf
	If ($iWidth - 36) < $Size[0] Then
		$K[0] = ($iWidth - 36) / $Size[0]
	EndIf
	If ($iHeight - 36) < $Size[1] Then
		$K[1] = ($iHeight - 36) / $Size[1]
	EndIf
	For $i = 0 To 1
		If $K[1] > $K[0] Then
			$Size[$i] *= $K[0]
		Else
			$Size[$i] *= $K[1]
		EndIf
	Next
	$hPreview = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
	$hGraphics = _GDIPlus_ImageGetGraphicsContext($hPreview)
	_GDIPlus_GraphicsClear($hGraphics, 0)
    $hBrush = _GDIPlus_BrushCreateSolid(0x28000000)
    _GDIPlus_GraphicsFillRect($hGraphics, 17, 17, $iWidth - 34, $iHeight - 34, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDrawRadialGradient($hGraphics, 17, 17, 12, 0x28000000, 0, -180, -90)
    _GDIPlus_GraphicsDrawRadialGradient($hGraphics, $iWidth - 17, 17, 12, 0x28000000, 0, -90, 0)
    _GDIPlus_GraphicsDrawRadialGradient($hGraphics, $iWidth - 17, $iHeight - 17, 12, 0x28000000, 0, 0, 90)
    _GDIPlus_GraphicsDrawRadialGradient($hGraphics,  17, $iHeight - 17, 12, 0x28000000, 0, 90, 180)
    For $i = 0 To 3
        $tRect = DllStructCreate($tagGDIPRECTF)
        For $j = 0 To 4
            DllStructSetData($tRect, $j + 1, $aPart[$i][$j])
        Next
        $hBrush = _GDIPlus_LineBrushCreateFromRectWithAngle($tRect, 0x28000000, 0, $aPart[$i][4], 0, 3)
        _GDIPlus_GraphicsFillRect($hGraphics, $aPart[$i][0], $aPart[$i][1], $aPart[$i][2], $aPart[$i][3], $hBrush)
        _GDIPlus_BrushDispose($hBrush)
    Next
	$hPen = _GDIPlus_PenCreate(0xFF606060)
	_GDIPlus_GraphicsDrawRect($hGraphics, 17, 17, $iWidth - 35, $iHeight - 35, $hPen)
	$hBrush = _GDIPlus_HatchBrushCreate($HatchStyleLargeCheckerBoard, 0xFFFFFFFF, 0xFFEBEBEB)
	_GDIPlus_GraphicsFillRect($hGraphics, 18, 18, $iWidth - 36, $iHeight - 36, $hBrush)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, Round(($iWidth - $Size[0]) / 2), Round(($iHeight - $Size[1]) / 2), $Size[0], $Size[1])
	_GDIPlus_GraphicsDispose($hGraphics)
	_GDIPlus_BrushDispose($hBrush)
	_GDIPlus_PenDispose($hPen)
	If ($hPreview) And ($fDelete) Then
		_GDIPlus_ImageDispose($hImage)
	EndIf
	Return $hPreview
EndFunc   ;==>_CreatePreview

Func _ShowPreview($hWnd, $hPreview, $iX, $iY, $iSpeed = 100, $fDelete = 0)

	Local $W, $H, $Size, $Timer, $Delay, $hGraphics, $hImage

	If Not IsHWnd($hWnd) Then
		Return 0
	EndIf
	$Size = _GDIPlus_ImageGetDimension($hPreview)
	If Not IsArray($Size) Then
		Return 0
	EndIf
	If ($iX <> -1) And ($iY <> -1) Then
		$iX -= $Size[0] / 2
		$iY -= $Size[1] / 2
	EndIf
	$hImage = _GDIPlus_BitmapCreateFromScan0($Size[0], $Size[1])
	$hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
	For $i = 15 To 255 Step 40
		$Timer = TimerInit()
		If $i = 255 Then
			$W = $Size[0]
			$H = $Size[1]
		Else
			$W = Round($Size[0] * Sin(2 * ATan(1) * $i / 255))
			If Mod($W, 2) Then
				$W += 1
			EndIf
			$H = Round($Size[1] * Sin(2 * ATan(1) * $i / 255))
			If Mod($H, 2) Then
				$H += 1
			EndIf
		EndIf
		_GDIPlus_GraphicsDrawImageRect($hGraphics, $hPreview, ($Size[0] - $W) / 2, ($Size[1] - $H) / 2, $W, $H)
		_WinAPI_UpdateLayeredWindowEx($hWnd, $iX, $iY, _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage), $i, 1)
		$Delay = $iSpeed / 7 - TimerDiff($Timer)
		If $Delay < 0 Then
			$Delay = 0
		EndIf
		$Timer = TimerInit()
		Do
		Until TimerDiff($Timer) >= $Delay
	Next
	_GDIPlus_GraphicsDispose($hGraphics)
	_GDIPlus_ImageDispose($hImage)
	If $fDelete Then
		_GDIPlus_ImageDispose($hPreview)
	EndIf
	Return 1
EndFunc   ;==>_ShowPreview

Func _GDIPlus_GraphicsDrawRadialGradient($hGraphics, $iX, $iY, $iRadius, $iARGB1, $iARGB2, $iStartAngle = 0, $iEndAngle = 360, $iStep = 5)

    If $iStep < 1 Then
        $iStep = 1
    EndIf

    Local $Xi = $iX - $iRadius, $Yi = $iY - $iRadius, $Di = 2 * $iRadius
    Local $hBrush, $hMatrix, $Smooth = _GDIPlus_GraphicsGetSmoothingMode($hGraphics)
    Local $Start = True

    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 0)
    $hBrush = _GDIPlus_LineBrushCreate(0, 0, $iRadius, 0, $iARGB1, $iARGB2, 3)
    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix, $iX, $iY)
    While $iStartAngle < $iEndAngle
        If $iStartAngle + $iStep > $iEndAngle Then
            $iStep = $iEndAngle - $iStartAngle
        EndIf
        If $Start Then
            _GDIPlus_MatrixRotate($hMatrix, $iStartAngle + $iStep / 2)
            $Start = False
        Else
            _GDIPlus_MatrixRotate($hMatrix, $iStep)
        EndIf
        _GDIPlus_LineBrushSetTransform($hBrush, $hMatrix)
        _GDIPlus_GraphicsFillPie($hGraphics, $Xi, $Yi, $Di, $Di, $iStartAngle, $iStep, $hBrush)
        $iStartAngle += $iStep
    WEnd
    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $Smooth)
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_BrushDispose($hBrush)
    Return 1
EndFunc   ;==>_GDIPlus_GraphicsDrawRadialGradient
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied [?]
как тебе такой расклад?
Ты добавил тень?

Я уже интегрировал твои примеры в утилиту, и переписывать всё снова не хочется, просто у меня немного другой стиль написания кода :smile:.


P.S.
Проблему с активацией окна я кажется решил.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied
Адаптировал вот так:

Код:
#include <APIConstants.au3>
#include <GDIP.au3>
#include <WinAPIEx.au3>

_GDIPlus_Startup()

$hForm = GUICreate('MyGUI', 360, 360, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetState()

$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\Test.png')

;~ $hPreview = _GDIPlus_ImageCreatePreview($hImage, 1, 3, 0, 400, 300)
$hPreview = _GDIPlus_ImageCreatePreview($hImage, 1, 3, 1)
If Not $hPreview Then Exit

_GDIPlus_ImageShowPreview($hForm, $hPreview, 1, 200)

Do
Until GUIGetMsg() = -3

Func _GDIPlus_ImageCreatePreview($hImage, $fDelete = 0, $iFrameMode = -1, $iAutoAdjustSize = 1, $iWidth = -1, $iHeight = -1)
	Local $aSize = _GDIPlus_ImageGetDimension($hImage)
	If Not IsArray($aSize) Then Return 0
	
	If $iAutoAdjustSize Then
		Local Const $iMin = 128, $iMax = 512
		Local $aTmpSize = $aSize, $aK[2] = [1, 1]
		
		For $i = 0 To 1
			If $aTmpSize[$i] > $iMax Then
				$aK[$i] = $iMax / $aTmpSize[$i]
			EndIf
		Next
		
		For $i = 0 To 1
			If $aK[1] > $aK[0] Then
				$aTmpSize[$i] *= $aK[0]
			Else
				$aTmpSize[$i] *= $aK[1]
			EndIf
			
			If $aTmpSize[$i] < $iMin Then $aTmpSize[$i] = $iMin
		Next
		
		$iWidth = $aTmpSize[0] + 36
		$iHeight = $aTmpSize[1] + 36
	EndIf
	
	Local $aPart[4][5] = [[17, 5, $iWidth - 34, 12, -90], [$iWidth - 17, 17, 12, $iHeight - 34, 0], [17, $iHeight - 17, $iWidth - 34, 12, 90], [5, 17, 12, $iHeight - 34, 180]]
	Local $aK[2] = [1, 1]
	Local $aSize, $tRect, $hGraphics, $hBrush, $hPen, $hPreview
	
	If ($iWidth - 36) < $aSize[0] Then
		$aK[0] = ($iWidth - 36) / $aSize[0]
	EndIf
	
	If ($iHeight - 36) < $aSize[1] Then
		$aK[1] = ($iHeight - 36) / $aSize[1]
	EndIf
	
	For $i = 0 To 1
		If $aK[1] > $aK[0] Then
			$aSize[$i] *= $aK[0]
		Else
			$aSize[$i] *= $aK[1]
		EndIf
	Next
	
	$hPreview = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
	$hGraphics = _GDIPlus_ImageGetGraphicsContext($hPreview)
	_GDIPlus_GraphicsClear($hGraphics, 0)
	
	$hBrush = _GDIPlus_BrushCreateSolid(0x28000000)
	_GDIPlus_GraphicsFillRect($hGraphics, 17, 17, $iWidth - 34, $iHeight - 34, $hBrush)
	_GDIPlus_BrushDispose($hBrush)
	
	$hBrush = _GDIPlus_HatchBrushCreate($HatchStyleLargeCheckerBoard, 0xFFFFFFFF, 0xFFEBEBEB)
	_GDIPlus_GraphicsFillRect($hGraphics, 18, 18, $iWidth - 36, $iHeight - 36, $hBrush)
	_GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, Round(($iWidth - $aSize[0]) / 2), Round(($iHeight - $aSize[1]) / 2), $aSize[0], $aSize[1])
	_GDIPlus_BrushDispose($hBrush)
	
	Local $iFrameWidth = 1, $iFrameColor = 0x606060
	
	Switch $iFrameMode
		Case 2, 3 ;Shadow (3 with inner frame, 2 without it)
			_GDIPlus_GraphicsDrawRadialGradient($hGraphics, 17, 17, 12, 0x28000000, 0, -180, -90)
			_GDIPlus_GraphicsDrawRadialGradient($hGraphics, $iWidth - 17, 17, 12, 0x28000000, 0, -90, 0)
			_GDIPlus_GraphicsDrawRadialGradient($hGraphics, $iWidth - 17, $iHeight - 17, 12, 0x28000000, 0, 0, 90)
			_GDIPlus_GraphicsDrawRadialGradient($hGraphics, 17, $iHeight - 17, 12, 0x28000000, 0, 90, 180)
			
			For $i = 0 To 3
				$tRect = DllStructCreate($tagGDIPRECTF)
				
				For $j = 0 To 4
					DllStructSetData($tRect, $j + 1, $aPart[$i][$j])
				Next
				
				$hBrush = _GDIPlus_LineBrushCreateFromRectWithAngle($tRect, 0x28000000, 0, $aPart[$i][4], 0, 3)
				_GDIPlus_GraphicsFillRect($hGraphics, $aPart[$i][0], $aPart[$i][1], $aPart[$i][2], $aPart[$i][3], $hBrush)
				_GDIPlus_BrushDispose($hBrush)
			Next
			
			If $iFrameMode = 3 Then ContinueCase
		Case 1 ;Simple frame
			$hPen = _GDIPlus_PenCreate('0xFF' & Hex($iFrameColor, 6), $iFrameWidth, 2)
			_GDIPlus_GraphicsDrawRect($hGraphics, 17, 17, $iWidth - 35, $iHeight - 35, $hPen)
			_GDIPlus_PenDispose($hPen)
		Case 0 ;No frame (Default)
			
	EndSwitch
	
	_GDIPlus_GraphicsDispose($hGraphics)
	
	If ($hPreview) And ($fDelete) Then
		_GDIPlus_ImageDispose($hImage)
	EndIf
	
	Return $hPreview
EndFunc

Func _GDIPlus_ImageShowPreview($hWnd, $hPreview, $fDelete = 0, $iSpeed = 100, $iX = -1, $iY = -1)
	Local $iW, $iH, $aSize, $iTimer, $iDelay, $hGraphics, $hImage
	
	If Not IsHWnd($hWnd) Then Return 0
	
	$aSize = _GDIPlus_ImageGetDimension($hPreview)
	If Not IsArray($aSize) Then Return 0
	
	If ($iX <> -1) And ($iY <> -1) Then
		$iX -= $aSize[0] / 2
		$iY -= $aSize[1] / 2
	EndIf
	
	$hImage = _GDIPlus_BitmapCreateFromScan0($aSize[0], $aSize[1])
	$hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
	
	For $i = 15 To 255 Step 40
		$iTimer = TimerInit()
		
		If $i = 255 Then
			$iW = $aSize[0]
			$iH = $aSize[1]
		Else
			$iW = Round($aSize[0] * Sin(2 * ATan(1) * $i / 255))
			If Mod($iW, 2) Then $iW += 1
			
			$iH = Round($aSize[1] * Sin(2 * ATan(1) * $i / 255))
			If Mod($iH, 2) Then $iH += 1
		EndIf
		
		_GDIPlus_GraphicsDrawImageRect($hGraphics, $hPreview, ($aSize[0] - $iW) / 2, ($aSize[1] - $iH) / 2, $iW, $iH)
		_WinAPI_UpdateLayeredWindowEx($hWnd, $iX, $iY, _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage), $i, 1)
		
		$iDelay = $iSpeed / 7 - TimerDiff($iTimer)
		If $iDelay < 0 Then $iDelay = 0
		
		$iTimer = TimerInit()
		
		Do
		Until TimerDiff($iTimer) >= $iDelay
	Next
	
	_GDIPlus_GraphicsDispose($hGraphics)
	_GDIPlus_ImageDispose($hImage)
	
	If $fDelete Then
		_GDIPlus_ImageDispose($hPreview)
	EndIf
	
	Return 1
EndFunc

Func _GDIPlus_GraphicsDrawRadialGradient($hGraphics, $iX, $iY, $iRadius, $iARGB1, $iARGB2, $iStartAngle = 0, $iEndAngle = 360, $iStep = 5)
	If $iStep < 1 Then $iStep = 1
	
	Local $Xi = $iX - $iRadius, $Yi = $iY - $iRadius, $Di = 2 * $iRadius
	Local $hBrush, $hMatrix, $Smooth = _GDIPlus_GraphicsGetSmoothingMode($hGraphics)
	Local $iStart = True
	
	_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 0)
	$hBrush = _GDIPlus_LineBrushCreate(0, 0, $iRadius, 0, $iARGB1, $iARGB2, 3)
	$hMatrix = _GDIPlus_MatrixCreate()
	_GDIPlus_MatrixTranslate($hMatrix, $iX, $iY)
	
	While $iStartAngle < $iEndAngle
		If $iStartAngle + $iStep > $iEndAngle Then
			$iStep = $iEndAngle - $iStartAngle
		EndIf
		
		If $iStart Then
			_GDIPlus_MatrixRotate($hMatrix, $iStartAngle + $iStep / 2)
			$iStart = False
		Else
			_GDIPlus_MatrixRotate($hMatrix, $iStep)
		EndIf
		
		_GDIPlus_LineBrushSetTransform($hBrush, $hMatrix)
		_GDIPlus_GraphicsFillPie($hGraphics, $Xi, $Yi, $Di, $Di, $iStartAngle, $iStep, $hBrush)
		$iStartAngle += $iStep
	WEnd
	
	_GDIPlus_GraphicsSetSmoothingMode($hGraphics, $Smooth)
	_GDIPlus_MatrixDispose($hMatrix)
	_GDIPlus_BrushDispose($hBrush)
	
	Return 1
EndFunc


Это нормально?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Нормально, только я бы не ставил задержку больше 100, т.к. через некоторое время это начинает сильно напрягать. Эффект плавного появления должен только улучшать визуализацию, а не притормаживать работу. IMHO, самое оптимальное время появления окна ~ так, как на смартфонах типа iPhone или Galaxy. Ориентируйся на это.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied
Что то странное с курсором...
На Win 7 пример из WinAPIEx задаёт пустой курсор корректно:

Код:
#Include <File.au3>
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)

Global $hPrev = _WinAPI_CopyCursor(_WinAPI_LoadCursor(0, 32512))

_WinAPI_SetSystemCursor(_WinAPI_LoadCursorFromFile(_GetEmptyCursorFile()), 32512)
Sleep(5000)
_WinAPI_SetSystemCursor($hPrev, 32512)

Func _GetEmptyCursorFile()
    Local $sTempFile = _TempFile()

	Local $sCurBin = '0x00000200010001010200000000003800000016000000280000000100000002000000010001000000000008000000CE0E0000D80E0000020000000000000000000000FFFFFF000000000080000000'

    Local $hFile = FileOpen($sTempFile, 2+16)
    FileWrite($hFile, $sCurBin)
    FileClose($hFile)

    Return $sTempFile
EndFunc


а на Win XP там чёрный квадрат, в чём причина?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

У меня на XP все нормально работает, т.е. курсор пропадает. Советую сделать не монохромное изображение, а 32 bpp.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied [?]
У меня на XP все нормально работает, т.е. курсор пропадает.
Какая XP у тебя?

Советую сделать не монохромное изображение, а 32 bpp
Пробовал, то же самое.


P.S.
Я тестирую на виртуалке, может быть в этом дело?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

CreatoR сказал(а):

Самая настоящая XP SP2 (English), стоит на работе. Все прекрасно работает.


Добавлено:
Сообщение автоматически объединено:

CreatoR сказал(а):
Я тестирую на виртуалке, может быть в этом дело?

Очень даже возможно. Забей.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Обновление!

1.2
* Снова переписан механизм показа эскиза (спасибо Yashied).
* Добавлена иконка в области уведомления (опционально).
* Добавлен диалог настроек (вызывается из трея, или через командную строку: /Settings).
* Добавлен диалог «О программе» (вызывается из трея, или через командную строку: /About).
* Теперь окно показа эскиза не берёт на себя фокус.
* Полноценная совместимость с Win XP.
* Иконка программы изменена.
* Исправлена проблема с вызовом действия переименования файла.
* Исправлена проблема с определением активной кнопки мышки (левша/правша).

Список текущих задач (ToDo):
  • Поддержка предпросмотра анимационных файлов (gif, apng, ani).
  • Отдельная обработка файлов иконок (перечисление всех размеров и выбор подходящего).
  • Масштабирование изображения во время просмотра эскиза, используя колёсико мышки, либо клавиши -/+.
  • Предоставить выбор метода вывода эскиза:
    - Удерживание первичной кнопки мышки (по умолчанию).
    - Удерживание средней кнопки мышки.
    - Удерживание вторичной кнопки мышки.
    - Удерживание x-кнопки мышки.
    - Наведение курсора мышки над файлом изображения. *
    - Двойное нажатие первичной кнопки мышки (эскиз отображается до тех пор пока первичная кнопка не нажата, или по ESC). *

* Под вопросом, возможно будет лишним
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

CreatoR сказал(а):

Код:
#Include <WinAPIEx.au3>

Global Const $sFile = @ScriptDir & '\MyIcon.ico'

Global Const $tagICOHEADER = 'ushort Reserved;ushort Type;ushort Count'
Global Const $tagICOENTRY = 'byte Width;byte Height;byte ColorCount;byte Reserved;ushort Planes;ushort BitCount;long Size;long Offset'
Global Const $tagIHDR = 'dword Width;dword Height;byte BitDepth;byte ColorType;byte CompressionMethod;byte FilterMethod;byte InterlaceMethod'

$iSize = FileGetSize($sFile)
$tData = DllStructCreate('byte[' & $iSize & ']')
$pData = DllStructGetPtr($tData)

$hFile = _WinAPI_CreateFile($sFile, 2, 2, 6)
_WinAPI_ReadFile($hFile, $pData, $iSize, $iSize)
_WinAPI_CloseHandle($hFile)

$tHdr = DllStructCreate($tagICOHEADER, $pData)
$Count = DllStructGetData($tHdr, 'Count')
For $i = 1 To $Count
	$tEntry = DllStructCreate($tagICOENTRY, $pData + 6 + 16 * ($i - 1))
	$pIcon = $pData + DllStructGetData($tEntry, 'Offset')
	$Offset = DllStructGetData($tEntry, 'Offset')
	If DllStructGetData(DllStructCreate('byte[8]', $pIcon), 1) = Binary('0x89504E470D0A1A0A') Then
		; PNG => Retrieve IHDR chunk data (always first chunk, offset = 8)
		$tHdr = DllStructCreate($tagIHDR, $pIcon + 16)
		$Width = _WinAPI_SwapDWord(DllStructGetData($tHdr, 'Width'))
		$Height = _WinAPI_SwapDWord(DllStructGetData($tHdr, 'Height'))
		$Png = ' (PNG)'
	Else
		; ICO => Retrieve BITMAPINFOHEADER structure
		$tHdr = DllStructCreate($tagBITMAPINFOHEADER, $pIcon)
		$Width = DllStructGetData($tHdr, 'biWidth')
		$Height = DllStructGetData($tHdr, 'biHeight') / 2
		$Png = ''
	EndIf
	ConsoleWrite($Width & ' x ' & $Height & ', ' & DllStructGetData($tEntry, 'BitCount') & 'bpp' & $Png & @CR)
Next



Добавлено:
Сообщение автоматически объединено:

Пустой курсор можно создать без дополнительного файла.

Код:
Func _CreateEmptyCursor()
	Local $hBitmap[2]
	$hBitmap[0] = _WinAPI_CreateBitmap(1, 1, 1, 16)
	$hBitmap[1] = _WinAPI_InvertANDBitmap(_WinAPI_CreateBitmap(1, 1, 1, 1), 1)
	$hCursor = _WinAPI_CreateIconIndirect($hBitmap[0], $hBitmap[1], 0, 0, 0)
	For $i = 0 To 1
		_WinAPI_DeleteObject($hBitmap[$i])
	Next
	Return $hCursor
EndFunc   ;==>_CreateEmptyCursor



Добавлено:
Сообщение автоматически объединено:

А еще для выбора цвета можно использовать это.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied
По поводу иконок.
Как теперь это использовать чтобы вытащить иконку как $hImage?
Может _WinAPI_ExtractIcon как то можно использовать?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

CreatoR сказал(а):
Как теперь это использовать чтобы вытащить иконку как $hImage?

_GDIPlus_BitmapCreateFromHICON() из GDIP.au3.


Добавлено:
Сообщение автоматически объединено:

Саму иконку получаешь с помощью _WinAPI_ShellExtractIcon() с заданными размерами.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied [?]
Саму иконку получаешь с помощью _WinAPI_ShellExtractIcon() с заданными размерами.
Я так понял брать нужно самую большую иконку (первую)?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Попробовал вот так:

Код:
...

	If StringRegExp($sImage_Path, '(?i)^.*\.(ico)$') Then
		$aIcons = __WinAPI_EnumFileIcons($sImage_Path)
	EndIf
	
	If IsArray($aIcons) Then
		$hIcon = _WinAPI_ShellExtractIcon($sImage_Path, $aIcons[1][0], $aIcons[1][1], $aIcons[1][2])
		$hImage = _GDIPlus_BitmapCreateFromHICON($hIcon)
	Else
		$hImage = _GDIPlus_ImageLoadFromFile($sImage_Path)
	EndIf

...


Func __WinAPI_EnumFileIcons($sFile)
	Local Const $tagICOHEADER = 'ushort Reserved;ushort Type;ushort Count'
	Local Const $tagICOENTRY = 'byte Width;byte Height;byte ColorCount;byte Reserved;ushort Planes;ushort BitCount;long Size;long Offset'
	Local Const $tagIHDR = 'dword Width;dword Height;byte BitDepth;byte ColorType;byte CompressionMethod;byte FilterMethod;byte InterlaceMethod'
	
	Local $iSize, $tData, $pData, $hFile, $tHdr, $iCount, $i, $tEntry, $pIcon, $iOffset, $iWidth, $iHeight, $sPng
	Local $aRet[1][1]
	
	$iSize = FileGetSize($sFile)
	$tData = DllStructCreate('byte[' & $iSize & ']')
	$pData = DllStructGetPtr($tData)
	
	$hFile = _WinAPI_CreateFile($sFile, 2, 2, 6)
	_WinAPI_ReadFile($hFile, $pData, $iSize, $iSize)
	_WinAPI_CloseHandle($hFile)
	
	$tHdr = DllStructCreate($tagICOHEADER, $pData)
	$iCount = DllStructGetData($tHdr, 'Count')
	
	For $i = 1 To $iCount
		$tEntry = DllStructCreate($tagICOENTRY, $pData + 6 + 16 * ($i - 1))
		$pIcon = $pData + DllStructGetData($tEntry, 'Offset')
		$iOffset = DllStructGetData($tEntry, 'Offset')
		
		If DllStructGetData(DllStructCreate('byte[8]', $pIcon), 1) = Binary('0x89504E470D0A1A0A') Then
			; PNG => Retrieve IHDR chunk data (always first chunk, offset = 8)
			$tHdr = DllStructCreate($tagIHDR, $pIcon + 16)
			$iWidth = _WinAPI_SwapDWord(DllStructGetData($tHdr, 'Width'))
			$iHeight = _WinAPI_SwapDWord(DllStructGetData($tHdr, 'Height'))
			$sPng = ' (PNG)'
		Else
			; ICO => Retrieve BITMAPINFOHEADER structure
			$tHdr = DllStructCreate($tagBITMAPINFOHEADER, $pIcon)
			$iWidth = DllStructGetData($tHdr, 'biWidth')
			$iHeight = DllStructGetData($tHdr, 'biHeight') / 2
			$sPng = ''
		EndIf
		
		$aRet[0][0] += 1
		ReDim $aRet[$aRet[0][0]+1][5]
		
		$aRet[$aRet[0][0]][0] = $i - 1
		$aRet[$aRet[0][0]][1] = $iWidth
		$aRet[$aRet[0][0]][2] = $iHeight
		$aRet[$aRet[0][0]][3] = DllStructGetData($tEntry, 'BitCount') ;bpp
		$aRet[$aRet[0][0]][4] = $sPng
	Next
	
	Return $aRet
EndFunc


но иконка получается не “чистая”.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Покажи скриншот.


Добавлено:
Сообщение автоматически объединено:

Я понял, это косяк GDI+. Используй следующую функцию.

Код:
#Include <GDIP.au3>
#Include <GDIPConstants.au3>
#Include <WinAPIEx.au3>

_GDIPlus_Startup()
$hIcon = _WinAPI_ShellExtractIcon(@ScriptDir & '\Test.ico', 0, 48, 48)
$hImage = _GDIPlus_BitmapCreateFromHICONEx($hIcon)
_GDIPlus_ImageSaveToFile($hImage, @ScriptDir & '\Test.png')
_WinAPI_DestroyIcon($hIcon)
_GDIPlus_Shutdown()

Func _GDIPlus_BitmapCreateFromHICONEx($hIcon)

	Local $W, $H, $tBITMAP, $tBits, $tData, $aIcon, $hImage = 0

	$aIcon = _WinAPI_GetIconInfo($hIcon)
	If (Not IsArray($aIcon)) Or (Not $aIcon[5]) Then
		Return 0
	EndIf
	If Not _WinAPI_IsAlphaBitmap($aIcon[5]) Then
		$hImage = _GDIPlus_BitmapCreateFromHICON($hIcon)
	Else
		Do
			$tBITMAP = DllStructCreate($tagBITMAP)
			If (Not _WinAPI_GetObject($aIcon[5], DllStructGetSize($tBITMAP), DllStructGetPtr($tBITMAP))) Or (DllStructGetData($tBITMAP, 'bmBitsPixel') <> 32) Then
				ExitLoop
			EndIf
			$W = DllStructGetData($tBITMAP, 'bmWidth')
			$H = DllStructGetData($tBITMAP, 'bmHeight')
			$tBits = DllStructCreate('byte[' & ($W * $H * 4) & ']')
			If Not _WinAPI_GetBitmapBits($aIcon[5], DllStructGetSize($tBits), DllStructGetPtr($tBits)) Then
				ExitLoop
			EndIf
			$hImage = _GDIPlus_BitmapCreateFromScan0($W, $H)
			If Not $hImage Then
				ExitLoop
			EndIf
			$tData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $W, $H, $GDIP_ILMWRITE, $GDIP_PXF32ARGB)
			If Not _WinAPI_MoveMemory(DllStructGetData($tData, 'Scan0'), DllStructGetPtr($tBits), DllStructGetSize($tBits)) Then
				; Nothing
			EndIf
			_GDIPlus_BitmapUnlockBits($hImage, $tData)
		Until 1
	EndIf
	For $i = 4 To 5
		_WinAPI_DeleteObject($aIcon[$i])
	Next
	Return $hImage
EndFunc   ;==>_GDIPlus_BitmapCreateFromHICONEx
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied [?]
Используй следующую функцию
Отлично, теперь отображается нормально.

А что ты думаешь по поводу масштабирования прокруткой, как это лучше всего реализовать?
Посмотри на блок с «If $bMouseWheelSroll_Event Then» в исходнике, там уже событие реализовано, вот как бы теперь изменять размеры эскиза в реальном времени?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

CreatoR, для получения списка размеров иконок, содержащихся в .ico файле используй лучше эту функцию. Там добавлена проверка на ошибки. Но самое главное, тебе придется написать алгоритм выбора наиболее подходящего размера иконки под окно программы. Кроме того, не всегда иконки идут от большего к меньшему размеру.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: SIP - Selected Image Preview (Предпросмотр выделенного изображения)

Yashied [?]
самое главное, тебе придется написать алгоритм выбора наиболее подходящего размера иконки под окно программы
А почему бы просто не брать самую большую иконку, и уже её выводить, как это делается с остальными изображениями?
Ведь изображение уже потом масштабируется в соответствии с заданными размерами.

Меня больше интересует реализация масштабирования прокруткой :whistle:.
 
Верх