Что нового

Создать свой файл ресурсов

Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Вот так?

Код:
$hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
	    $hFormat = _GDIPlus_StringFormatCreate()
	    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
	    $hFont = _GDIPlus_FontCreate($hFamily, 10, 0)
	    $tLayout = _GDIPlus_RectFCreate(24, 5, 0, 0)
	    $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "Window title", $hFont, $tLayout, $hFormat)
		_GDIPlus_GraphicsSetTextRenderingHint($hGraphic, 3)
	    _GDIPlus_GraphicsDrawStringEx($hGraphic, "Window title", $hFont, $aInfo[0], $hFormat, $hBrush)
		_GDIPlus_FontDispose($hFont)
	    _GDIPlus_FontFamilyDispose($hFamily)
	    _GDIPlus_StringFormatDispose($hFormat)
	    _GDIPlus_BrushDispose($hBrush)


Можно ещё с тёмной тенью сделать

Код:
; Пишем заголовок окна --------------------------------------------
		$hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
	    $hFormat = _GDIPlus_StringFormatCreate()
	    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
	    $hFont = _GDIPlus_FontCreate($hFamily, 10, 0)
	    $tLayout = _GDIPlus_RectFCreate(25, 6, 0, 0)
	    $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "Window title", $hFont, $tLayout, $hFormat)
	    _GDIPlus_GraphicsDrawStringEx($hGraphic, "Window title", $hFont, $aInfo[0], $hFormat, $hBrush)

		$aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "Window title", $hFont, $tLayout, $hFormat)
		DllStructSetData($aInfo[0], 1, 24)
		DllStructSetData($aInfo[0], 2, 5)
		$hBrush = _GDIPlus_BrushCreateSolid(0xFFFEFEFE)
	    _GDIPlus_GraphicsDrawStringEx($hGraphic, "Window title", $hFont, $aInfo[0], $hFormat, $hBrush)

		_GDIPlus_FontDispose($hFont)
	    _GDIPlus_FontFamilyDispose($hFamily)
	    _GDIPlus_StringFormatDispose($hFormat)
	    _GDIPlus_BrushDispose($hBrush)


А вообще, я думал такие данные будут в самом файле скина хранится
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Лучше 4, но только для прозрачного окна.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
А что эта функция делает?

Код:
_GDIPlus_GraphicsSetTextRenderingHint($hGraphic, 4)


Я посмотрел, 2й параметр если 1,2,3 - ни чего, 4 - размазывает текст, 5 - 3 color
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Вот функция _SkinSave(), которая создает .ask файл из указанных файлов (массив $aSource). Исходные файлы могут быть абсолютно любые (не обязательно картинки).

Ограничения:

  • Размер каждого включаемого файла не должен превышать размер свободной оперативной памяти, т.е. фильмы в HD качестве указывать не стоит. :smile:
  • Имя файла (исключая путь) сохраняется в файл .ask и не должно превышать 127 символов, в противном случае оно будет урезано.
  • Длина строки комментария ограничена в 127 символов, в противном случае она будет урезана.

Если что не понятно, спрашивайте.

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

Global Const $tagHEADER = _
		'dword  Signature;' & _
		'dword  Version;' & _
		'dword  FileSize;' & _
		'dword  Count;' & _
		'dword  Reserved[4];' & _
		'wchar  Comment[128]'

Global Const $tagRECORD = _
		'dword  Offset;' & _
		'dword  Size;' & _
		'dword  Reserved[2];' & _
		'wchar  Name[128]'

#cs

-------------------------------------------
|               *.ask, v1.0               |
-------------------------------------------
| Header         | $tagHEADER | 288 bytes |
-------------------------------------------
| Record1        | $tagRECORD | 272 bytes |
-------------------------------------------
|                   ...                   |
-------------------------------------------
| RecordN        | $tagRECORD | 272 bytes |
-------------------------------------------
|                   ...                   |
-------------------------------------------
| Data1          |   BYTE[*]  |         * |
-------------------------------------------
|                   ...                   |
-------------------------------------------
| DataN          |   BYTE[*]  |         * |
-------------------------------------------

#ce

$Source = _FileListToArray(@ScriptDir, '*.png', 1)
If Not _SkinSave(@ScriptDir & '\Test.ask', 'MySkin', $Source, 1) Then
	Switch @error
		Case 1
			MsgBox(16, 'Error', 'Array of sources is incorrect.')
		Case 2
			MsgBox(16, 'Error', 'Source not found or is an empty file.')
		Case 3
			MsgBox(16, 'Error', 'Unable to read source.')
		Case 4
			MsgBox(16, 'Error', 'Unable to write data.')
		Case Else

	EndSwitch
EndIf

Func _SkinSave($sFile, $sComment, Const ByRef $aSource, $iStart = 0, $iEnd = -1)

#cs

Error codes:

1 - Array of sources is incorrect
2 - Source not found or is an empty file
3 - Unable to read source
4 - Unable to write data

#ce

	Local $hFile, $hSource, $tBuffer, $pBuffer, $tData, $pData, $tRecord, $Bytes, $Count, $Size, $Offset = 0, $Lenght = 0, $Error = 4
	Local $SEM = _WinAPI_SetErrorMode($SEM_FAILCRITICALERRORS)
	Local $tHeader = DllStructCreate($tagHEADER)
	Local $pHeader = DllStructGetPtr($tHeader)

	If Not IsArray($aSource) Then
		Return SetError(1, 0, 0)
	EndIf
	If $iStart < 0 Then
		$iStart = 0
	EndIf
	If ($iEnd < 0) Or ($iEnd > UBound($aSource) - 1) Then
		$iEnd = UBound($aSource) - 1
	EndIf
	$Count = $iEnd - $iStart + 1
	If $Count < 1 Then
		Return SetError(1, 0, 0)
	EndIf
	For $i = $iStart To $iEnd
		If Not FileGetSize($aSource[$i]) Then
			Return SetError(2, 0, 0)
		EndIf
	Next
	Do
		$hFile = _WinAPI_CreateFileEx($sFile, $CREATE_ALWAYS, $GENERIC_WRITE)
		If @error Then
			ExitLoop
		EndIf
		If Not _WinAPI_WriteFile($hFile, $pHeader, DllStructGetSize($tHeader), $Bytes) Then
			ExitLoop
		EndIf
		$Offset += $Bytes
		$tRecord = DllStructCreate($tagRECORD)
		$Size = DllStructGetSize($tRecord)
		$tData = DllStructCreate('byte[' & ($Size * $Count) & ']')
		If @error Then
			; Nothing
		EndIf
		$pData = DllStructGetPtr($tData)
		If Not _WinAPI_WriteFile($hFile, $pData, DllStructGetSize($tData), $Bytes) Then
			ExitLoop
		EndIf
		$Offset += $Bytes
		For $i = $iStart To $iEnd
			Do
				$Error = 3
				$hSource = _WinAPI_CreateFileEx($aSource[$i], $OPEN_EXISTING, $GENERIC_READ)
				If @error Then
					ExitLoop
				EndIf
				$Bytes = _WinAPI_GetFileSize($hSource)
				$tBuffer = DllStructCreate('byte[' & $Bytes & ']')
				$pBuffer = DllStructGetPtr($tBuffer)
				If @error Then
					ExitLoop
				EndIf
				If Not _WinAPI_ReadFile($hSource, $pBuffer, $Bytes, $Bytes) Then
					ExitLoop
				EndIf
				$Error = 0
			Until 1
			If $hSource Then
				_WinAPI_CloseHandle($hSource)
			EndIf
			If $Error Then
				ExitLoop 2
			EndIf
			$tRecord = DllStructCreate($tagRECORD, $pData + $Lenght)
			DllStructSetData($tRecord, 'Offset', $Offset)
			DllStructSetData($tRecord, 'Size', $Bytes)
			DllStructSetData($tRecord, 'Name', _WinAPI_PathStripPath($aSource[$i]))
			$Error = 4
			If Not _WinAPI_WriteFile($hFile, $pBuffer, $Bytes, $Bytes) Then
				ExitLoop 2
			EndIf
			$Offset += $Bytes
			$Lenght += $Size
		Next
		DllStructSetData($tHeader, 'Signature', 0x004B5341)
		DllStructSetData($tHeader, 'Version', 0x00000001)
		DllStructSetData($tHeader, 'FileSize', $Offset)
		DllStructSetData($tHeader, 'Count', $Count)
		DllStructSetData($tHeader, 'Comment', $sComment)
		If _WinAPI_SetFilePointer($hFile, 0, $FILE_BEGIN) = -1 Then
			ExitLoop
		EndIf
		If Not _WinAPI_WriteFile($hFile, $pHeader, DllStructGetSize($tHeader), $Bytes) Then
			ExitLoop
		EndIf
		If Not _WinAPI_WriteFile($hFile, $pData, DllStructGetSize($tData), $Bytes) Then
			ExitLoop
		EndIf
		$Error = 0
	Until 1
	If $hFile Then
		_WinAPI_CloseHandle($hFile)
	EndIf
	_WinAPI_SetErrorMode($SEM)
	If $Error Then
		Return SetError($Error, FileDelete($sFile), 0)
	Else
		Return 1
	EndIf
EndFunc   ;==>_SkinSave


P.S

Функцию для чтения .ask файлов напишу завтра (сегодня).
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Пишет ошибки:

Код:
D:\Documents and Settings\Admin\Рабочий стол\Aero\Dark Azure\AutoIt v3 Script (2).au3(96,77) : ERROR: _WinAPI_CreateFileEx() called with wrong number of args.
        $hFile = _WinAPI_CreateFileEx($sFile, $CREATE_ALWAYS, $GENERIC_WRITE)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\Program Files\AutoIt3\Include\WinAPIEx.au3(4421,123) : REF: definition of _WinAPI_CreateFileEx().
Func _WinAPI_CreateFileEx($sFile, $iCreation, $iAccess, $iShare, $iFlagsAndAttributes = 0, $tSecurity = 0, $hTemplate = 0)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\Documents and Settings\Admin\Рабочий стол\Aero\Dark Azure\AutoIt v3 Script (2).au3(118,92) : ERROR: _WinAPI_CreateFileEx() called with wrong number of args.
                $hSource = _WinAPI_CreateFileEx($aSource[$i], $OPEN_EXISTING, $GENERIC_READ)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\Program Files\AutoIt3\Include\WinAPIEx.au3(4421,123) : REF: definition of _WinAPI_CreateFileEx().
Func _WinAPI_CreateFileEx($sFile, $iCreation, $iAccess, $iShare, $iFlagsAndAttributes = 0, $tSecurity = 0, $hTemplate = 0)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\Documents and Settings\Admin\Рабочий стол\Aero\Dark Azure\AutoIt v3 Script (2).au3(122,54) : ERROR: _WinAPI_GetFileSize(): undefined function.
                $Bytes = _WinAPI_GetFileSize($hSource)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
D:\Documents and Settings\Admin\Рабочий стол\Aero\Dark Azure\AutoIt v3 Script (2).au3 - 3 error(s), 0 warning(s)
!>02:37:11 AU3Check ended.rc:2

В _WinAPI_CreateFileEx() нужно указать 4й параметр
Функции _WinAPI_GetFileSize() нет в WinAPIEx.au3

Версия AutoIt 3.3.8.0
WinAPIEx.au3 - последняя


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

Извиняюсь, скачал WinAPIEx.au3 для 3.3.8.0, всё прекрасно работает :smile:
 

Yashied

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

[0][0] - Количество элементов в массиве (n)
[0][1] - Комментарий (то, что указали в функции _SkinSave(), например название скина)
[n][0] - Дескриптор GDI+ битмапа или непосредственно двоичные данные в зависимости от параметра $fBinary.
[n][1] - Имя исходного файла (просто информация, ни на что не влияет)

Если $fBinary = 0, то все данные в .ask файле должны представлять собой файлы изображений (.bmp, .png и т.д.), в противном случае функция возвратит ошибку (@error = 6).

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

Global Const $tagHEADER = _
		'dword  Signature;' & _
		'dword  Version;' & _
		'dword  FileSize;' & _
		'dword  Count;' & _
		'dword  Reserved[4];' & _
		'wchar  Comment[128]'

Global Const $tagRECORD = _
		'dword  Offset;' & _
		'dword  Size;' & _
		'dword  Reserved[2];' & _
		'wchar  Name[128]'

#cs

-------------------------------------------
|               *.ask, v1.0               |
-------------------------------------------
| Header         | $tagHEADER | 288 bytes |
-------------------------------------------
| Record1        | $tagRECORD | 272 bytes |
-------------------------------------------
|                   ...                   |
-------------------------------------------
| RecordN        | $tagRECORD | 272 bytes |
-------------------------------------------
|                   ...                   |
-------------------------------------------
| Data1          |   BYTE[*]  |         * |
-------------------------------------------
|                   ...                   |
-------------------------------------------
| DataN          |   BYTE[*]  |         * |
-------------------------------------------

#ce

$Data = _FileListToArray(@ScriptDir, '*.png', 1)
If Not _SkinSave(@ScriptDir & '\Test.ask', 'MySkin', $Data, 1) Then
	Switch @error
		Case 1
			MsgBox(16, 'Error', 'Array of sources is incorrect.')
		Case 2
			MsgBox(16, 'Error', 'Source not found or is an empty file.')
		Case 3
			MsgBox(16, 'Error', 'Unable to read source.')
		Case 4
			MsgBox(16, 'Error', 'Unable to write data.')
		Case Else

	EndSwitch
	Exit
EndIf

$Data = _SkinLoad(@ScriptDir & '\Test.ask')
Switch @error
	Case 0
		_ArrayDisplay($Data, 'Test.ask')
	Case 1
		MsgBox(16, 'Error', 'Unable to read file.')
	Case 2
		MsgBox(16, 'Error', 'The file is not a "*.ask" file.')
	Case 3
		MsgBox(16, 'Error', 'Incorrect file version (support only v1.0).')
	Case 4
		MsgBox(16, 'Error', 'Incorrect file size.')
	Case 5
		MsgBox(16, 'Error', 'Invalid data.')
	Case 6
		MsgBox(16, 'Error', 'GDI+ error.')
	Case Else

EndSwitch

Func _SkinSave($sFile, $sComment, Const ByRef $aSource, $iStart = 0, $iEnd = -1)

#cs

Error codes:

1 - Array of sources is incorrect
2 - Source not found or is an empty file
3 - Unable to read source
4 - Unable to write data

#ce

	Local $hFile, $hSource, $tBuffer, $pBuffer, $tData, $pData, $tRecord, $Bytes, $Count, $Size, $Offset = 0, $Lenght = 0, $Error = 4
	Local $SEM = _WinAPI_SetErrorMode($SEM_FAILCRITICALERRORS)
	Local $tHeader = DllStructCreate($tagHEADER)
	Local $pHeader = DllStructGetPtr($tHeader)

	If Not IsArray($aSource) Then
		Return SetError(1, 0, 0)
	EndIf
	If $iStart < 0 Then
		$iStart = 0
	EndIf
	If ($iEnd < 0) Or ($iEnd > UBound($aSource) - 1) Then
		$iEnd = UBound($aSource) - 1
	EndIf
	$Count = $iEnd - $iStart + 1
	If $Count < 1 Then
		Return SetError(1, 0, 0)
	EndIf
	For $i = $iStart To $iEnd
		If Not FileGetSize($aSource[$i]) Then
			Return SetError(2, 0, 0)
		EndIf
	Next
	Do
		$hFile = _WinAPI_CreateFileEx($sFile, $CREATE_ALWAYS, $GENERIC_WRITE)
		If @error Then
			ExitLoop
		EndIf
		If Not _WinAPI_WriteFile($hFile, $pHeader, DllStructGetSize($tHeader), $Bytes) Then
			ExitLoop
		EndIf
		$Offset += $Bytes
		$tRecord = DllStructCreate($tagRECORD)
		$Size = DllStructGetSize($tRecord)
		$tData = DllStructCreate('byte[' & ($Size * $Count) & ']')
		If @error Then
			; Nothing
		EndIf
		$pData = DllStructGetPtr($tData)
		If Not _WinAPI_WriteFile($hFile, $pData, DllStructGetSize($tData), $Bytes) Then
			ExitLoop
		EndIf
		$Offset += $Bytes
		For $i = $iStart To $iEnd
			Do
				$Error = 3
				$hSource = _WinAPI_CreateFileEx($aSource[$i], $OPEN_EXISTING, $GENERIC_READ)
				If @error Then
					ExitLoop
				EndIf
				$Bytes = _WinAPI_GetFileSize($hSource)
				$tBuffer = DllStructCreate('byte[' & $Bytes & ']')
				$pBuffer = DllStructGetPtr($tBuffer)
				If @error Then
					ExitLoop
				EndIf
				If Not _WinAPI_ReadFile($hSource, $pBuffer, $Bytes, $Bytes) Then
					ExitLoop
				EndIf
				$Error = 0
			Until 1
			If $hSource Then
				_WinAPI_CloseHandle($hSource)
			EndIf
			If $Error Then
				ExitLoop 2
			EndIf
			$tRecord = DllStructCreate($tagRECORD, $pData + $Lenght)
			DllStructSetData($tRecord, 'Offset', $Offset)
			DllStructSetData($tRecord, 'Size', $Bytes)
			DllStructSetData($tRecord, 'Name', _WinAPI_PathStripPath($aSource[$i]))
			$Error = 4
			If Not _WinAPI_WriteFile($hFile, $pBuffer, $Bytes, $Bytes) Then
				ExitLoop 2
			EndIf
			$Offset += $Bytes
			$Lenght += $Size
		Next
		DllStructSetData($tHeader, 'Signature', 0x004B5341)
		DllStructSetData($tHeader, 'Version', 0x00000001)
		DllStructSetData($tHeader, 'FileSize', $Offset)
		DllStructSetData($tHeader, 'Count', $Count)
		DllStructSetData($tHeader, 'Comment', $sComment)
		If _WinAPI_SetFilePointer($hFile, 0, $FILE_BEGIN) = -1 Then
			ExitLoop
		EndIf
		If Not _WinAPI_WriteFile($hFile, $pHeader, DllStructGetSize($tHeader), $Bytes) Then
			ExitLoop
		EndIf
		If Not _WinAPI_WriteFile($hFile, $pData, DllStructGetSize($tData), $Bytes) Then
			ExitLoop
		EndIf
		$Error = 0
	Until 1
	If $hFile Then
		_WinAPI_CloseHandle($hFile)
	EndIf
	_WinAPI_SetErrorMode($SEM)
	If $Error Then
		Return SetError($Error, FileDelete($sFile), 0)
	Else
		Return 1
	EndIf
EndFunc   ;==>_SkinSave

Func _SkinLoad($sFile, $fBinary = 0)

#cs

Return 2D array:

[0][0] - Number of items in aray
[0][1] - Skin comment (for example skin name)
[i][0] - Handle to GDI+ bitmap or binary data directly depending on the second parameter
[i][1] - The source file name (just info)

Error codes:

1 - Unable to read file
2 - The file is not a "*.ask" file
3 - Incorrect file version (support only v1.0)
4 - Incorrect file size
5 - Invalid data
6 - GDI+ error

#ce

	Local $hFile, $tBuffer, $tData, $pData, $tRecord, $Bytes, $Count, $Size, $Lenght = 0, $Error = 1, $Result = 0
	Local $SEM = _WinAPI_SetErrorMode($SEM_FAILCRITICALERRORS)
	Local $tHeader = DllStructCreate($tagHEADER)
	Local $GDIP = False

	Do
		$hFile = _WinAPI_CreateFileEx($sFile, $OPEN_EXISTING, $GENERIC_READ)
		If @error Then
			ExitLoop
		EndIf
		If Not _WinAPI_ReadFile($hFile, DllStructGetPtr($tHeader), DllStructGetSize($tHeader), $Bytes) Then
			ExitLoop
		EndIf
		If DllStructGetData($tHeader, 'Signature') <> 0x004B5341 Then
			$Error = 2
			ExitLoop
		EndIf
		If DllStructGetData($tHeader, 'Version') <> 0x00000001 Then
			$Error = 3
			ExitLoop
		EndIf
		If DllStructGetData($tHeader, 'FileSize') <> _WinAPI_GetFileSize($hFile) Then
			$Error = 4
			ExitLoop
		EndIf
		$Count = DllStructGetData($tHeader, 'Count')
		If $Count < 1 Then
			$Error = 5
			ExitLoop
		EndIf
		$tRecord = DllStructCreate($tagRECORD)
		$Size = DllStructGetSize($tRecord)
		$tData = DllStructCreate('byte[' & ($Size * $Count) & ']')
		If @error Then
			$Error = 5
			ExitLoop
		EndIf
		$pData = DllStructGetPtr($tData)
		If Not _WinAPI_ReadFile($hFile, $pData, DllStructGetSize($tData), $Bytes) Then
			ExitLoop
		EndIf
		Dim $Result[$Count + 1][2]
		$Result[0][0] = $Count
		$Result[0][1] = DllStructGetData($tHeader, 'Comment')
		If Not $fBinary Then
			_GDIPlus_Startup()
			$GDIP = 1
		EndIf
		For $i = 0 To $Count - 1
			$tRecord = DllStructCreate($tagRECORD, $pData + $Lenght)
			If _WinAPI_SetFilePointer($hFile, DllStructGetData($tRecord, 'Offset'), $FILE_BEGIN) = -1 Then
				$Error = 5
				ExitLoop 2
			EndIf
			$Bytes = DllStructGetData($tRecord, 'Size')
			$tBuffer = DllStructCreate('byte[' & $Bytes & ']')
			If @error Then
				$Error = 5
				ExitLoop 2
			EndIf
			If Not _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), $Bytes, $Bytes) Then
				ExitLoop 2
			EndIf
			If $fBinary Then
				$Result[$i + 1][0] = DllStructGetData($tBuffer, 1)
			Else
				$Result[$i + 1][0] = _CreateGDIPBitmap($tBuffer)
				If Not $Result[$i + 1][0] Then
					$Error = 6
					ExitLoop 2
				EndIf
			EndIf
			$Result[$i + 1][1] = DllStructGetData($tRecord, 'Name')
			$Lenght += $Size
		Next
		$Error = 0
	Until 1
	If $hFile Then
		_WinAPI_CloseHandle($hFile)
	EndIf
	_WinAPI_SetErrorMode($SEM)
	If $GDIP Then
		If ($Error) And (IsArray($Result)) Then
			For $i = 1 To $Count
				If IsPtr($Result[$i][0]) Then
					_GDIPlus_BitmapDispose($Result[$i][0])
				Else
					ExitLoop
				EndIf
			Next
		EndIf
		_GDIPlus_Shutdown()
	EndIf
	If $Error Then
		Return SetError($Error, 0, 0)
	Else
		Return $Result
	EndIf
EndFunc   ;==>_SkinLoad

Func _CreateGDIPBitmap(ByRef $tData)

	Local $hMem, $pMem, $pStream, $hBitmap, $Size

	$Size = DllStructGetSize($tData)
	If @error Then
		Return 0
	EndIf
	$hMem = DllCall('kernel32.dll', 'ptr', 'GlobalAlloc', 'uint', 2, 'ulong_ptr', $Size)
	If @error Then
		Return 0
	EndIf
	Do
		$pMem = DllCall('kernel32.dll', 'ptr', 'GlobalLock', 'ptr', $hMem[0])
		If @error Then
			ExitLoop
		EndIf
		If Not _WinAPI_MoveMemory($pMem[0], DllStructGetPtr($tData), $Size) Then
			ExitLoop
		EndIf
		DllCall('kernel32.dll', 'int', 'GlobalUnlock', 'ptr', $hMem[0])
		If @error Then
			ExitLoop
		EndIf
		$pStream = _WinAPI_CreateStreamOnHGlobal($hMem[0])
		If @error Then
			; Nothing
		EndIf
	Until 1
	If @error Then
		DllCall('kernel32.dll', 'ptr', 'GlobalFree', 'ptr', $hMem[0])
		Return 0
	EndIf
;~	_GDIPlus_Startup()
	$hBitmap = _GDIPlus_CreateBitmapFromStream($pStream)
	If @error Then
		; Nothing
	EndIf
;~	_GDIPlus_Shutdown()
	_WinAPI_ReleaseStream($pStream)
	Return $hBitmap
EndFunc   ;==>_CreateGDIPBitmap

Func _GDIPlus_CreateBitmapFromStream($pStream)

	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromStream', 'ptr', $pStream, 'ptr*', 0)

	If (@error) Or ($Ret[0]) Then
		Return SetError(@error, @extended, 0)
	EndIf
	Return $Ret[2]
EndFunc   ;==>_GDIPlus_CreateBitmapFromStream
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Все заносимые ресурсы должны находиться в одной папке со скриптом, что не совсем удобно.
Это так задумано ?
Может есть смысл задавать в качестве параметра и папку,содержащую ресурсы. (или только папку)
Вроде несложно.
 

Yashied

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

:blink:

В функцию передается массив с путями того, что нужно добавить. Сделайте список файлов хоть с разных дисков. А указывать только папку не очень хорошо, т.к. может оказаться важным последовательность занесения файлов.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Понятно.
Насколько я понял ресурсами могут быть и файлы ".ico".
Только почему-то не все файлы занеслись .
Количество в массиве сохранилось, однако большая часть элементов массива- пустые строки ?




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

Ха... Судя по всему это издержки ф-ии_ArrayDisplay
Вопрос снимается.
 

Yashied

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

Вы не внимательно смотрели код. Если $fBinary = 0, то вместо двоичных данных возвращается именно то, что вы делаете с помощью функции _GDIPlus_LoadBinaryImage(), т.е. дескрипторы GDI+ битмапов. Кроме того, вы включили в код эту функцию, но она уже там есть - _CreateGDIPBitmap(). Я специально вынес соответствующий код в отдельную функцию, предвидя, что она вам понадобится. А еще _GDIPlus_LoadBinaryImage() будет провоцировать утечку памяти, т.к. объект Stream нужно освобождать, см. мою функцию. Вообщем лучше так:

Код:
#Include <APIConstants.au3>
#Include <GDIPlus.au3>
#Include <GUIConstantsEx.au3>
#Include <WinAPIEx.au3>
#Include <Array.au3>
#Include <Skinfile.au3>

_GDIPlus_Startup()

$Path = FileOpenDialog("Выберите скин", @ScriptDir, "AutoIt Skin(*.ask)")
If Not @error Then
    $hPart = _SkinLoad($Path)
	If Not @error Then
		ReDim $hPart[$hPart[0][0] + 1][3]
		For $i = 1 To $hPart[0][0]
			$Size = _GDIPlus_GetImageDimension($hPart[$i][0])
			For $j = 1 To 2
				$hPart[$i][$j] = $Size[$j - 1]
			Next
		Next
	Else
		Exit
	EndIf
Else
    Exit
EndIf

$hForm = GUICreate('', -1, -1, -1, -1, BitOR($WS_POPUP, $WS_SIZEBOX), $WS_EX_LAYERED)
_WinAPI_UpdateLayeredWindowEx($hForm, -1, -1, ComposeBitmap(400, 400, $hPart), 255, 1)
GUIRegisterMsg($WM_GETMINMAXINFO, 'WM_GETMINMAXINFO')
GUIRegisterMsg($WM_NCHITTEST, 'WM_NCHITTEST')
GUIRegisterMsg($WM_SIZING, 'WM_SIZING')
GUIRegisterMsg($WM_MOVE, 'WM_MOVE')

$iPos = WinGetPos($hForm)
$hGui = GUICreate('', 382, 363, $iPos[0] + 8, $iPos[1] + 28, BitOR($WS_CLIPCHILDREN, $WS_POPUP), -1, $hForm)
GUISetBkColor(0xEDEAE4)
$hExit = GUICtrlCreateButton("Exit", 20, 20, 50, 20)

GUISetState(@SW_SHOW, $hGui)
GUISetState(@SW_SHOW, $hForm)

While True
    Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE, $hExit
			Exit
	EndSwitch
WEnd

Func ComposeBitmap($iWidth, $iHeight, ByRef $hPart)

	Local $hGraphic, $hImage, $hThumb, $hBitmap

    If IsArray($hPart) Then
	    $hImage = _GDIPlus_CreateBitmapFromScan0($iWidth, $iHeight)
	    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[1][0], 0, 0, $hPart[1][1], $hPart[1][2])
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[3][0], $iWidth - $hPart[3][1], 0, $hPart[3][1], $hPart[3][2])
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[9][0], $iWidth - $hPart[9][1], $iHeight - $hPart[9][2], $hPart[9][1], $hPart[9][2])
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hPart[7][0], 0, $iHeight - $hPart[7][2], $hPart[7][1], $hPart[7][2])
	    $hThumb = _GDIPlus_GetImageThumbnail($hPart[2][0], $iWidth - ($hPart[1][1] + $hPart[3][1]), $hPart[2][2])
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $hPart[1][1], 0, $iWidth - ($hPart[1][1] + $hPart[3][1]), $hPart[2][2])
	    _GDIPlus_ImageDispose($hThumb)
	    $hThumb = _GDIPlus_GetImageThumbnail($hPart[6][0], $hPart[6][1], $iHeight - ($hPart[3][2] + $hPart[7][2]))
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $iWidth - $hPart[6][1], $hPart[3][2], $hPart[6][1], $iHeight - ($hPart[3][2] + $hPart[7][2]))
	    _GDIPlus_ImageDispose($hThumb)
	    $hThumb = _GDIPlus_GetImageThumbnail($hPart[8][0], $iWidth - ($hPart[7][1] + $hPart[9][1]), $hPart[8][2])
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $hPart[7][1], $iHeight - $hPart[8][2], $iWidth - ($hPart[7][1] + $hPart[9][1]), $hPart[8][2])
	    _GDIPlus_ImageDispose($hThumb)
	    $hThumb = _GDIPlus_GetImageThumbnail($hPart[4][0], $hPart[4][1], $iHeight - ($hPart[1][2] + $hPart[7][2]))
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, 0, $hPart[1][2], $hPart[4][1], $iHeight - ($hPart[1][2] + $hPart[7][2]))
	    _GDIPlus_ImageDispose($hThumb)
	    $hThumb = _GDIPlus_GetImageThumbnail($hPart[5][0], $iWidth - ($hPart[4][1] + $hPart[6][1]), $iHeight - ($hPart[1][2] + $hPart[7][2]))
	    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hThumb, $hPart[4][1], $hPart[1][2], $iWidth - ($hPart[4][1] + $hPart[6][1]), $iHeight - ($hPart[1][2] + $hPart[7][2]))
	    _GDIPlus_ImageDispose($hThumb)

        ; Ставим иконку ---------------------------------------------------
        $hIcon = _WinAPI_ShellExtractIcon(@AutoItExe, -99, 16, 16)
		$aInfo = _WinAPI_GetIconInfo($hIcon)
		$tBits = DllStructCreate('byte[' & (4 * 16 * 16) & ']')
		$pBits = DllStructGetPtr($tBits)
		_WinAPI_GetBitmapBits($aInfo[5], DllStructGetSize($tBits), $pBits)
		$hBitmap = _GDIPlus_CreateBitmapFromScan0(16, 16, 4 * 16, $GDIP_PXF32ARGB, $pBits)
		_WinAPI_DestroyIcon($hIcon)
		For $i = 4 To 5
            _WinAPI_DeleteObject($aInfo[$i])
        Next
		_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 5, 5, 16, 16)
		_GDIPlus_ImageDispose($hBitmap)

        ; Пишем заголовок окна --------------------------------------------
		$hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
	    $hFormat = _GDIPlus_StringFormatCreate()
	    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
	    $hFont = _GDIPlus_FontCreate($hFamily, 10, 0)
	    $tLayout = _GDIPlus_RectFCreate(25, 6, 0, 0)
	    $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "Window title", $hFont, $tLayout, $hFormat)
	    _GDIPlus_GraphicsDrawStringEx($hGraphic, "Window title", $hFont, $aInfo[0], $hFormat, $hBrush)

		$aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "Window title", $hFont, $tLayout, $hFormat)
		DllStructSetData($aInfo[0], 1, 24)
		DllStructSetData($aInfo[0], 2, 5)
		$hBrush = _GDIPlus_BrushCreateSolid(0xFFFEFEFE)
	    _GDIPlus_GraphicsDrawStringEx($hGraphic, "Window title", $hFont, $aInfo[0], $hFormat, $hBrush)

		_GDIPlus_FontDispose($hFont)
	    _GDIPlus_FontFamilyDispose($hFamily)
	    _GDIPlus_StringFormatDispose($hFormat)
	    _GDIPlus_BrushDispose($hBrush)

	    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
	    _GDIPlus_GraphicsDispose($hGraphic)
	    _GDIPlus_ImageDispose($hImage)
	Else
        Return SetError(@error, @extended, 0)
    EndIf

	Return $hBitmap
EndFunc

Func _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $iTextRenderingHint)

    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipSetTextRenderingHint', 'ptr', $hGraphics, 'int', $iTextRenderingHint)

    If (@error) Or ($Ret[0]) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return 1
EndFunc   ;==>_GDIPlus_GraphicsSetTextRenderingHint

Func _GDIPlus_CreateBitmapFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $iWidth, 'int', $iHeight, 'int', $iStride, 'int', $iPixelFormat, 'ptr', $pScan0, 'ptr*', 0)
	If (@error) Or ($Ret[0]) Then
		Return SetError(@error, @extended, 0)
	EndIf
	Return $Ret[6]
EndFunc

Func _GDIPlus_GetImageDimension($hImage)

	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageDimension', 'ptr', $hImage, 'float*', 0, 'float*', 0)

	If (@error) Or ($Ret[0]) Then
		Return SetError(@error, @extended, 0)
	EndIf

	Local $Result[2]

	For $i = 0 To 1
		$Result[$i] = $Ret[$i + 2]
	Next
	Return $Result
EndFunc   ;==>_GDIPlus_GetImageDimension

Func _GDIPlus_GetImageThumbnail($hImage, $iWidth, $iHeight)
	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipGetImageThumbnail', 'ptr', $hImage, 'uint', $iWidth, 'uint', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)
	If (@error) Or ($Ret[0]) Then
		Return SetError(@error, @extended, 0)
	EndIf
	Return $Ret[4]
EndFunc

Func WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hForm
			Local $tMMI = DllStructCreate('long Reserved[2];long MaxSize[2];long MaxPosition[2];long MinTrackSize[2];long MaxTrackSize[2]', $lParam)
			DllStructSetData($tMMI, 'MinTrackSize', 40, 1)
			DllStructSetData($tMMI, 'MinTrackSize', 40, 2)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc

Func WM_SIZING($hWnd, $iMsg, $wParam, $lParam)
	Switch $hWnd
		Case $hForm
			Local $iPos = _WinAPI_GetPosFromRect(DllStructCreate($tagRECT, $lParam))
			_WinAPI_UpdateLayeredWindowEx($hWnd, $iPos[0], $iPos[1], ComposeBitmap($iPos[2], $iPos[3], $hPart), 255, 1)
			WinMove($hGui, "", $iPos[0] + 8, $iPos[1] + 28, $iPos[2] - 17, $iPos[3] - 37)
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc

Func WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $hForm
            Switch _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
                Case $HTCLIENT
                    Local $Info = GUIGetCursorInfo($hForm)
                    If (Not @error) And ($Info[1] < 25) Then
                        Return $HTCAPTION
                    EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
    Switch $hWnd
        Case $hForm
            Local $Pos = _WinAPI_GetPosFromRect(_WinAPI_GetWindowRect($hForm))
            WinMove($hGui, "", $Pos[0] + 8, $Pos[1] + 28, $Pos[2] - 17, $Pos[3] - 37)
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc


И обратите внимание на WM_GETMINMAXINFO(). В ней задаются минимално допустимые размеры окна.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Не, я понял что функция возвращает и handle картинки, но тогда не работает _GDIPlus_ImageGetWidth() и _GDIPlus_ImageGetHeight(), и скрипт вылетает.

Теперь всё, работает, спасибо :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Если $fBinary = 0 (по умолчанию), то возвращается handle, Если $fBinary = 1, то двоичные данные.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
А в файл скина можно впихнуть ini файл в котором указываются все настроики для данного скина, например:

BkColor ; Цвет фона дочернего окна
Size ; координаты дочернего относительно предка
TitleColor ; Цвет текста в Title
Icon ; Координаты иконки окна

и т.д. и т.п
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Можно, но потом придется переводить двоичные данные в текстовый вид или писать .ini на диск, что не есть хорошо. Удобнее будет все это поместить в двоичном виде в заголовок .ask. Но для начала нужно определиться с количеством записей (сколько их должно быть).
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Их будет много, записи окна и всех его элементов, наверное это решится когда весь скин (UDF) будет готов.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied,
Огромное Вам спасибо за классные функции.

Хочу немного изменить их под свои нужды (добавить удаление и замену блоков данных с другим размером). Скажите, пожалуйста, при замене (удалении) определенного блока файл надо перезаписывать с места начала нового блока и до конца или возможно как-то по другому сделать? Спасибо.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Структура файла не позволяет удаление/добавление данных "на лету", т.к. таблица записей имеет фиксированную длину. Или я вас неправильно понял?
 
Верх