Cool![]()
![]()
Cool![]()
![]()
Hier mein Lösungsvorschlag:
#include <Array.au3>
$sInput = "das ist ein Hund\das ist eine Banane\das ist eine Katze\das ist ein Kakadu"
$sInput = StringReplace($sInput, "\", " \ ")
$aSplit = StringSplit($sInput, " ", 3)
$aUnique = _ArrayUnique($aSplit)
For $i = 1 To $aUnique[0]
If $aSplit[$i] = "\" Then ContinueLoop
StringReplace($sInput, $aUnique[$i], $aUnique[$i])
$aCount = StringRegExp($sInput, "\b" & $aUnique[$i] & "\b", 3)
$iCount = UBound($aCount)
If $iCount > 1 Then
For $j = 0 To UBound($aSplit) - 1
If $iCount > 1 Then
If $aUnique[$i] = $aSplit[$j] Then
$aSplit[$j] = ""
$iCount -= 1
EndIf
EndIf
Next
EndIf
Next
$sResult = ""
For $i = 0 To UBound($aSplit) - 1
If $aSplit[$i] <> "" Then
$sResult &= $aSplit[$i]
If $aSplit[$i] <> "\" Then
If $i < UBound($aSplit) - 1 Then
If $aSplit[$i + 1] <> "\" And $aSplit[$i + 1] <> " " Then $sResult &= " "
EndIf
EndIf
EndIf
Next
ConsoleWrite($sResult & @CRLF)
Alles anzeigen
Kleines Update auf v0.80: nun mit Assembler Unterstützung.
Danke an Andy für Assembleit2 - you rock man. ![]()
Wow, das neue Skriopt ist ja deutlich schneller als das alte.
Nur für 1/15/16/24/32-Bit TGA Bild Dateien.
Für 8-Bit Bilder muss die Farbe jeweils aus der Farbtabelle kopiert werden, was bei großen Bildern dauert.
Hier ein kleines Skript zum Parsen von Targa (TGA) Bild Dateien (1-Bit, 8-Bit, 15-Bit, 16-Bit, 24-Bit und 32-Bit). Falls erfolgreich, wird ein GDI+ Bitmap erstellt.
Da der Code nativ in AutoIt geschrieben ist, dauert das Umwandelt für größere Bilder entsprechend.
Download nativ AutoIt Code: _GDIPlus_TGAImageLoadFromFile v0.85.au3
v0.80 mit Assembler Unterstützung, aber ohne RLE Support!:
;Coded by UEZ
#AutoIt3Wrapper_Compile_Both=y
#AutoIt3Wrapper_UseX64=n
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Memory.au3>
#include <WinAPIFiles.au3>
; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_TGAImageLoadFromFile
; Description ...: Loads an uncompressed TGA image file (1/8/15/16/24/32-bit) and converts it to a GDI+ bitmap format.
; Syntax ........: _GDIPlus_TGAImageLoadFromFile($sFile[, $bPrintInfo = False.])
; Parameters ....: $sFile - TGA file name to load from disk.
; $bPrintInfo - [optional] Prints some information about the TGA image to console. Default is False.
; Return values .: Success: GDI+ bitmap handle
; Failure: error 1 - file cannot be opened
; error 2 - TGA image is not in one of these formats: 1/8/15/16/24/32-bit
; error 3 - unsupported TGA image type
; error 4 - unable to read file to struct
; error 5 - unknown TGA pixel depth
; error 6 - return bitmap cannot be created
; Version .......: v0.80 build 2019-10-23 beta
; Author ........: UEZ - thanks to AndyG for Assembleit2
; Remarks .......: No RLE compressed TGA image support yet!
; Related .......: _GDIPlus_BitmapCreateFromScan0, _GDIPlus_ImageRotateFlip, DllStructCreate, _WinAPI_CreateFile, _WinAPI_SetFilePointer
; Link ..........: https://www.loc.gov/preservation/digital/formats/fdd/fdd000180.shtml, http://www.fileformat.info/format/tga/egff.htm
; Example .......: Yes
; ===============================================================================================================================
Func _GDIPlus_TGAImageLoadFromFile($sFile, $bPrintInfo = False)
Local Const $hFile = _WinAPI_CreateFile($sFile, 2, 2)
If Not $hFile Then Return SetError(1, 0, 0)
Local Const $tagTGAHeader = "align 1;byte idLength;byte colormapType;byte imageType;word firstEntryIndex;word colormapLength;byte colormapEntrySize;word xOrigin;word yOrigin;word width;word height;byte pixelDepth;byte imageDescriptor"
Local Const $tagTGAFooter = "dword extAreaOffset;dword devDirOffset;byte imageID[18]"
Local Const $tagTGAExtention = "align 1;word extSize;byte authorName[41];byte authorComments[324];word timeM;word timeD;word timeY;word timeHr;word timeMin;word timeSec;byte jobName[41];word jobTimeHr;word jobTimeMin;word jobTimeSec;byte swID[41];word swVersionNr;byte swVersionLetter;long keyColor;word pxAspectRatioNum;word pxAspectRatioDom;word gammaNum;word gammaDom;dword colCorrOffset;dword postStampOffset;dword scanLineOffset;byte attribType"
Local Const $tTGAHeader = DllStructCreate($tagTGAHeader)
Local Const $tTGAFooter = DllStructCreate($tagTGAFooter)
Local Const $tTGAExtention = DllStructCreate($tagTGAExtention)
Local $dwBytesRead, $tTGAImageID, $tagTGAImageID
_WinAPI_ReadFile($hFile, $tTGAHeader, DllStructGetSize($tTGAHeader), $dwBytesRead)
If $tTGAHeader.idLength > 0 Then
$tagTGAImageID = "byte imageID[" & $tTGAHeader.idLength & "]"
$tTGAImageID = DllStructCreate($tagTGAImageID)
_WinAPI_ReadFile($hFile, $tTGAImageID, $tTGAHeader.idLength, $dwBytesRead)
EndIf
Local Const $iPxDepth = $tTGAHeader.pixelDepth
If Not BitOR($iPxDepth = 32, $iPxDepth = 24, $iPxDepth = 16, $iPxDepth = 15, $iPxDepth = 8, $iPxDepth = 1) Then
_WinAPI_CloseHandle($hFile)
Return SetError(2, 0, 0)
EndIf
#cs
ImageType Image Data Type Colormap Encoding
0 No image data included in file No No
1 Colormapped image data Yes No
2 Truecolor image data No No
3 Monochrome image data No No
9 Colormapped image data Yes Yes
10 Truecolor image data No Yes
11 Monochrome image data No Yes
#ce
If Not BitOR($tTGAHeader.imageType = 0x01, $tTGAHeader.imageType = 0x02, $tTGAHeader.imageType = 0x03) Then
_WinAPI_CloseHandle($hFile)
Return SetError(3, 0, 0)
EndIf
Local $iW = $tTGAHeader.width, $iH = $tTGAHeader.height, $bytesPerPixel = $iPxDepth / 8, $colorwidth = $tTGAHeader.colormapEntrySize / 8, _
$colorTblSize = $tTGAHeader.colormapLength * $colorwidth
If $tTGAHeader.colormapEntrySize < 24 Then $bytesPerPixel = 4
Local Const $dwBufferSize = FileGetSize($sFile)
Local $tSrcBmp = DllStructCreate("ubyte color[" & $dwBufferSize + $colorTblSize & "]")
_WinAPI_ReadFile($hFile, $tSrcBmp, $dwBufferSize + $colorTblSize, $dwBytesRead)
_WinAPI_SetFilePointer($hFile, -26, $FILE_END)
_WinAPI_ReadFile($hFile, $tTGAFooter, 26, $dwBytesRead)
Local $sFooter = StringTrimRight(BinaryToString($tTGAFooter.imageID), 1), $iOffset = 0, $iOffset2
If Not StringCompare($sFooter, "TRUEVISION-XFILE.") Then ;read extension information to struct if available
$iOffset = $tTGAFooter.extAreaOffset
_WinAPI_SetFilePointer($hFile, $iOffset, $FILE_BEGIN)
_WinAPI_ReadFile($hFile, $tTGAExtention, 0x01EF, $dwBytesRead)
EndIf
_WinAPI_CloseHandle($hFile)
If $dwBytesRead = 0 Then Return SetError(4, _WinAPI_GetLastError(), 0)
If $bPrintInfo Then
ConsoleWrite("idLength: " & $tTGAHeader.idLength & @CRLF)
ConsoleWrite("colormapType: " & $tTGAHeader.colormapType & @CRLF)
ConsoleWrite("imageType: " & $tTGAHeader.imageType & @CRLF)
ConsoleWrite("firstEntryIndex: " & $tTGAHeader.firstEntryIndex & @CRLF)
ConsoleWrite("colormapLength: " & $tTGAHeader.colormapLength & @CRLF)
ConsoleWrite("colormapEntrySize: " & $tTGAHeader.colormapEntrySize & @CRLF)
ConsoleWrite("xOrigin: " & $tTGAHeader.xOrigin & @CRLF)
ConsoleWrite("yOrigin: " & $tTGAHeader.yOrigin & @CRLF)
ConsoleWrite("width: " & $tTGAHeader.width & @CRLF)
ConsoleWrite("height: " & $tTGAHeader.height & @CRLF)
ConsoleWrite("pixelDepth: " & $iPxDepth & @CRLF)
ConsoleWrite("imageDescriptor: " & $tTGAHeader.imageDescriptor & @CRLF)
If $tTGAHeader.idLength > 0 Then ConsoleWrite("ImageID: " & RemoveNullChars($tTGAImageID.imageID) & @CRLF)
If $iOffset Then
ConsoleWrite("authorName: " & RemoveNullChars($tTGAExtention.authorName) & @CRLF)
ConsoleWrite("authorComments: " & RemoveNullChars($tTGAExtention.authorComments) & @CRLF)
ConsoleWrite("jobName: " & RemoveNullChars($tTGAExtention.jobName) & @CRLF)
ConsoleWrite("swID: " & RemoveNullChars($tTGAExtention.swID) & @CRLF)
EndIf
EndIf
Local Static $tDestBmp ;must be static otherwise bitmap data might get corrupted or in worst case script will crash
Local $stride, $iPixelFormat
Switch $iPxDepth
Case 1 ;1-bit
$iPixelFormat = $GDIP_PXF01INDEXED
$stride = BitAND(($iW * 1) + 1, BitNOT(1))
$tDestBmp = DllStructCreate("uint color[" & $stride * $iH + 1 & "];")
Case 8, 24
$iPixelFormat = $GDIP_PXF24RGB
$stride = BitAND(($iW * 3) + 3, BitNOT(3))
$tDestBmp = DllStructCreate("uint color[" & $stride * $iH + 1 & "];")
Case 15, 16
$iPixelFormat = $GDIP_PXF16RGB555
$stride = BitAND(($iW * 2) + 2, BitNOT(2))
$tDestBmp = DllStructCreate("uint color[" & $stride * $iH + 1 & "];")
Case 32
$iPixelFormat = $GDIP_PXF32ARGB
$stride = $iW * 4
$tDestBmp = DllStructCreate("uint color[" & $stride * $iH + 1 & "];")
Case Else
Return SetError(5, 0, 0)
EndSwitch
If Mod($stride, 4) <> 0 Then $stride += 4 - Mod($stride, 4)
Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH, $iPixelFormat, $stride, $tDestBmp)
If @error Or Not $hBitmap Then Return SetError(6, @error, 0)
Local $fTimer = TimerInit()
Local $x, $x1, $y, $t1
Local Const $hDLL = DllOpen("msvcrt.dll")
Local Const $tagParam = "ptr tSrcBmp;ptr tDestBmp;dword strideSrc;dword strideDest;dword w;dword h;dword colorTblSize;dword t1;dword t2"
Local $tParam
If @AutoItX64 Then
$tParam = _DLLStructCreate64($tagParam)
Else
$tParam = DLLStructCreate($tagParam)
EndIf
$tParam.tSrcBmp = DllStructGetPtr($tSrcBmp)
$tParam.tDestBmp = DllStructGetPtr($tDestBmp)
$tParam.strideDest = $stride
$tParam.w = ($iW - 1)
$tParam.h = ($iH - 1)
$tParam.colorTblSize = $colorTblSize
Switch $iPxDepth
Case 1 ;1-bit
For $y = 0 To $iH - 1
$t1 = $y * $stride
DllCall($hDLL, "ptr:cdecl", "memcpy", "ptr", DllStructGetPtr($tDestBmp) + $t1, "ptr", DllStructGetPtr($tSrcBmp) + BitShift($t1, 3), "uint", $stride)
Next
Case 8 ;8-bit
ConsoleWrite("Using Assembler code to speed-up..." & @CRLF)
;if a color table is available, just use it
If $tTGAHeader.colormapType = 1 Then
Local $tMapColorTbl = DllStructCreate("ubyte bgr[" & $colorTblSize & "]", DllStructGetPtr($tSrcBmp, "color") + $tTGAHeader.firstEntryIndex)
Local $tParam2, $tagParam2 = "align 1;ptr tSrcBmp;ptr tDestBmp;ptr colormap;dword strideSrc;dword strideDest;dword w;dword h;dword colorTblSize;dword colorwidth;dword t1;dword t2;byte r5;byte g5;byte b5;"
If @AutoItX64 Then
$tParam2 = _DLLStructCreate64($tagParam2)
Else
$tParam2 = DllStructCreate($tagParam2)
EndIf
$tParam2.tSrcBmp = DllStructGetPtr($tSrcBmp)
$tParam2.tDestBmp = DllStructGetPtr($tDestBmp)
$tParam2.colormap = DllStructGetPtr($tMapColorTbl)
$tParam2.strideSrc = $iW
$tParam2.strideDest = $stride
$tParam2.colorwidth = $colorwidth
$tParam2.w = ($iW - 1)
$tParam2.h = ($iH - 1)
$tParam2.colorTblSize = $colorTblSize
Switch @AutoItX64
Case False
Local Const $bBinASM8cm_x86 = Binary("0x608B7C242431C990909090909090909089C8F7670C03471C89472489C8F7671089472831DB8B472401D8030789C231C08A02F767208B570801C28B32B803000000F7E303472803470489C5837F200275476689F26683E21F66C1E20388572E6689F26681E2E00366C1EA0566C1E20388572D6689F26681E2007C66C1EA0A66C1E20388572C31C00A472CC1E0080A472DC1E0080A472E89C6897500433B5F147684413B4F180F8665FFFFFF61C20400")
Local $tBinASM8cm_x86 = DllStructCreate("ubyte asm[" & BinaryLen($bBinASM8cm_x86) & "]")
$tBinASM8cm_x86.asm = $bBinASM8cm_x86
DllCallAddress("none", DllStructGetPtr($tBinASM8cm_x86), "ptr", DllStructGetPtr($tParam2))
Case Else
Local Const $bBinASM8cm_x64 = Binary("0x575653554989CF41BE000000009090904489F041F7671841034728418947304489F041F7671C418947344531ED418B47304401E84903074889C24831C08A0241F7672C498B57104801C2448B0A4831C048C7C00300000041F7E541034734490347084989C041837F2C02755A4831D2664489CA6683E21F66C1E2034188573A4831D2664489CA6681E2E00366C1EA0566C1E203418857394831D2664489CA6681E2007C66C1EA0A66C1E2034188573831C0410A4738C1E008410A4739C1E008410A473A4189C145890841FFC5453B6F200F8657FFFFFF41FFC6453B77240F862DFFFFFF5D5B5E5FC20800")
Local $tBinASM8cm_x64 = _DLLStructCreate64("ubyte asm[" & BinaryLen($bBinASM8cm_x64) & "]")
$tBinASM8cm_x64.asm = $bBinASM8cm_x64
DllCallAddress("none", DllStructGetPtr($tBinASM8cm_x64), "ptr", DllStructGetPtr($tParam2))
EndSwitch
Else ;convert it 1:1 directly
Switch @AutoItX64
Case False
$tParam.strideSrc = $iW
$tParam.colorTblSize -= 2
Local Const $bBinASM8_x86 = Binary("0x8B7C2404BB00000000B900000000909089C8F7670889471C89C8F7670C8947208B471C01D8034718030789C252B803000000F7E30347200347045A8B328930433B5F1076DB31DB413B4F1476C3C20400")
Local $tBinASM8_x86 = DllStructCreate("ubyte asm[" & BinaryLen($bBinASM8_x86) & "]")
$tBinASM8_x86.asm = $bBinASM8_x86
DllCallAddress("none", DllStructGetPtr($tBinASM8_x86), "ptr", DllStructGetPtr($tParam))
Case Else
$tParam.strideSrc = $iW
Local Const $bBinASM8_x64 = Binary("0x575653554989CF49836F2002BB00000000B9000000009090909090909090909089C841F767104989C289C841F767144989C34D89D04901D84D0347204D030748C7C00300000048F7E34C01D8490347084D8B08448908FFC3413B5F1876D44831DBFFC1413B4F1C76B75D5B5E5FC20800")
Local $tBinASM8_x64 = _DLLStructCreate64("ubyte asm[" & BinaryLen($bBinASM8_x64) & "]")
$tBinASM8_x64.asm = $bBinASM8_x64
DllCallAddress("none", DllStructGetPtr($tBinASM8_x64), "ptr", DllStructGetPtr($tParam))
EndSwitch
EndIf
Case 15, 16, 24, 32 ;15/16/24/32-bit, as the bitmap format is the same we can use memcpy to copy the pixel data directly to the memory.
;Exeptions are 15/16/24-bit images whose width is not a divider of 4!
If BitOR($iPxDepth = 15, $iPxDepth = 16, $iPxDepth = 24) And Mod($iW, 4) Then
ConsoleWrite("Using Assembler code to speed-up..." & @CRLF)
Switch $iPxDepth
Case 15, 16
$tParam.strideSrc = $iW * 2
Switch @AutoItX64
Case False
Local Const $bBinASM1516_x86 = Binary("0x8B7C2404BB00000000B900000000909089C8F7670889471C89C8F7670C894720B802000000F7E35003471C034718030789C2580347200347048B32668930433B5F1076DC31DB413B4F1476C4C20400")
Local $tBinASM1516_x86 = DllStructCreate("ubyte asm[" & BinaryLen($bBinASM1516_x86) & "]")
$tBinASM1516_x86.asm = $bBinASM1516_x86
DllCallAddress("none", DllStructGetPtr($tBinASM1516_x86), "ptr", DllStructGetPtr($tParam))
Case Else
Local Const $bBinASM1516_x64 = Binary("0x575653554989CFBB00000000B90000000090909090909090909090909090909089C841F767104989C189C841F767144989C25389D8D1E04C89D24801C2490357084D89C84901C04D0347204D0307498B00488902FFC3FFC3413B5F1876D55BFFC1413B4F1C76B95D5B5E5FC20800")
Local $tBinASM1516_x64 = _DLLStructCreate64("ubyte asm[" & BinaryLen($bBinASM1516_x64) & "]")
$tBinASM1516_x64.asm = $bBinASM1516_x64
DllCallAddress("none", DllStructGetPtr($tBinASM1516_x64), "ptr", DllStructGetPtr($tParam))
EndSwitch
Case 24
$tParam.strideSrc = $iW * 3
Switch @AutoItX64
Case False
Local Const $bBinASM24_x86 = Binary("0x8B7C2404BB00000000B900000000909089C8F7670889471C89C8F7670C894720B803000000F7E35003471C034718030789C2580347200347048B328930433B5F1076DD31DB413B4F1476C5C20400")
Local $tBinASM24_x86 = DllStructCreate("ubyte asm[" & BinaryLen($bBinASM24_x86) & "]")
$tBinASM24_x86.asm = $bBinASM24_x86
DllCallAddress("none", DllStructGetPtr($tBinASM24_x86), "ptr", DllStructGetPtr($tParam))
Case Else
Local Const $bBinASM24_x64 = Binary("0x575653554989CF4831C990909090909089C841F767104989C189C841F767144989C24831DB48C7C00300000048F7E34C89D24801C2490357084D89C84901C04D0347204D0307498B00488902FFC3FFC3413B5F1876CFFFC1413B4F1C76B25D5B5E5FC20800")
Local $tBinASM24_x64 = _DLLStructCreate64("ubyte asm[" & BinaryLen($bBinASM24_x64) & "]")
$tBinASM24_x64.asm = $bBinASM24_x64
DllCallAddress("none", DllStructGetPtr($tBinASM24_x64), "ptr", DllStructGetPtr($tParam))
EndSwitch
EndSwitch
Else
For $y = 0 To $iH - 1
$t1 = $y * $stride
DllCall($hDLL, "ptr:cdecl", "memcpy", "ptr", DllStructGetPtr($tDestBmp) + $t1, "ptr", DllStructGetPtr($tSrcBmp) + $t1, "uint", $stride)
Next
EndIf
EndSwitch
ConsoleWrite(TimerDiff($fTimer) & " ms" & @CRLF)
DllClose($hDLL)
;TGA image is stored bottom up in file. Need to flip it.
If BitAND($tTGAHeader.imageDescriptor, 0x30) <> 0x20 Then _GDIPlus_ImageRotateFlip($hBitmap, $GDIP_Rotate180FlipX)
$tSrcBmp = 0
Return $hBitmap
EndFunc ;==>_GDIPlus_TGAImageLoadFromFile
; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name ..........: RemoveNullChars
; Description ...: Converts a null terminated binary string to a string
; Author ........: UEZ
; ===============================================================================================================================
Func RemoveNullChars($bin)
Local $a = StringRegExp($bin, "[[:xdigit:]+]{2}", 3), $s, $i
If @error Then Return $s
For $i = 0 To UBound($a) - 1
If $a[$i] = "00" Then ExitLoop
$s &= Chr(Dec($a[$i]))
Next
Return $s
EndFunc ;==>RemoveNullChars
; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name ..........: _DLLStructCreate64
; Description ...: Creates a struct for x64 assembler code execution
; Author ........: AndyG
; ===============================================================================================================================
Func _DLLStructCreate64($struct) ;align auf 16-byte Adresse
Local $temp = DllStructCreate($struct)
Local $tempsize = DllStructGetSize($temp) + 64
Local $ptr = DllStructGetPtr($struct)
Local $a1 = Mod(Number($ptr), 64)
Local $temp = 0
Local $mem = _MemVirtualAlloc($ptr + $a1, $tempsize, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
Local $mem_dllstructcreate64_internal = $mem
Local $a2 = Mod(Number($mem), 64) ;rest div 16 adresse = offset
Local $sstruct = DllStructCreate($struct, (Number($mem) - $a2 + 64))
Return $sstruct ;auf 16 alingned pointer
EndFunc ;==>_DLLStructCreate64
Global $sFile = FileOpenDialog("Select a TGA file", "", "TGA image(*.tga)")
If @error Then Exit
_GDIPlus_Startup()
Global $hImage = _GDIPlus_TGAImageLoadFromFile($sFile, True)
If @error Then
ConsoleWrite(@error & " / " & @extended & @CRLF)
_GDIPlus_Shutdown()
Exit
EndIf
;save result
;~ _GDIPlus_ImageSaveToFile($hImage, @ScriptDir & "\Converted.png")
;~ ShellExecute(@ScriptDir & "\Converted.png")
Global $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage)
Global $hGui = GUICreate("TGA Image Loader by UEZ", $iW, $iH)
GUISetState()
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, 0, 0, $iW, $iH)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
Exit
Case $GUI_EVENT_RESTORE
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, 0, 0, $iW, $iH)
EndSwitch
WEnd
Alles anzeigen
Falls eine TGA Datei nicht umgewandelt werden kann, dann bitte hier melden.
Danke.
Ich bastele gerade noch an einer Version, die auch 8-bit und 16-bit darstellen kann. Leider ist AutoIt zu langsam für größere Bilder.
8-Bit funktioniert jetzt, 16-bit noch nicht...
funkey hatte auch mal dies bezgl. was gebastelt -> Use tga pictures in AutoIt only
funkey kannst ja mal be Gelegenheit den Link zum Anhang fixen. ![]()
Hier die native langsame AutoIt Version ohne RLE Dekodierung und 8 Bit Support:
;Coded by UEZ build 2019-09-17 beta
;8 bit doesn't work yet as the color table is the default one which cause wrong colors
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPIFiles.au3>
Func _GDIPlus_TGAImageLoadFromFile($sFile)
Local $tagTGAHeader = "align 1;byte idLength;byte colormapType;byte imageType;word firstEntryIndex;word colormapLength;byte colormapEntrySize;word xOrigin;word yOrigin;word width;word height;byte pixelDepth;byte imageDescriptor"
Local $tTGAHeader = DllStructCreate($tagTGAHeader)
Local $dwBytesRead, $hFile = _WinAPI_CreateFile($sFile, 2, 2)
_WinAPI_ReadFile($hFile, $tTGAHeader, DllStructGetSize($tTGAHeader), $dwBytesRead)
If $tTGAHeader.idLength > 0 Then _WinAPI_SetFilePointer($hFile, $tTGAHeader.idLength, $FILE_CURRENT)
If Not BitOR($tTGAHeader.pixelDepth = 32, $tTGAHeader.pixelDepth = 24, $tTGAHeader.pixelDepth = 8) Then
_WinAPI_CloseHandle($hFile)
Return SetError(1, 0, 0)
EndIf
If Not BitOR($tTGAHeader.imageType = 0x01, $tTGAHeader.imageType = 0x02) Then ;Only support uncompressed true color and grayscale images
_WinAPI_CloseHandle($hFile)
Return SetError(2, 0, 0)
EndIf
Local $iW = $tTGAHeader.width, $iH = $tTGAHeader.height, $bytesPerPixel = $tTGAHeader.pixelDepth / 8
Local $dwPitch = $iW * $bytesPerPixel, $dwBufferSize = $dwPitch * $iH
Local $tBuffer = DllStructCreate("byte color[" & $dwBufferSize & "]")
_WinAPI_ReadFile($hFile, $tBuffer, $dwBufferSize, $dwBytesRead)
_WinAPI_CloseHandle($hFile)
Local Static $tPixel = DllStructCreate("byte color[" & $iW * $iH * $bytesPerPixel & "];") ;must be static otherwise data in struct will be destroyed! Bug?!?!
Local $stride = $iW * $bytesPerPixel, $iPixelFormat
If Mod($stride, 4) <> 0 Then $stride += 4 - Mod($stride, 4)
Switch $bytesPerPixel
Case 1
$iPixelFormat = $GDIP_PXF08INDEXED
Case 3
$iPixelFormat = $GDIP_PXF24RGB
Case 4
$iPixelFormat = $GDIP_PXF32ARGB
EndSwitch
Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH, $iPixelFormat, $stride, $tPixel)
If @error Or Not $hBitmap Then Return SetError(3, 0, 0)
Local $x, $x1, $x2, $y, $iOffset, $r, $g, $b, $a
For $y = 0 To ($iH - 1) * $bytesPerPixel
$iOffset = $y * $iW
For $x = 0 To ($iW - 1) * $bytesPerPixel
$x1 = $x * $bytesPerPixel
$b = $tBuffer.color($iOffset + $x1 + 1)
$g = $tBuffer.color($iOffset + $x1 + 2)
$r = $tBuffer.color($iOffset + $x1 + 3)
$x2 = $x * $bytesPerPixel
$tPixel.color($iOffset + $x2 + 1) = $b
$tPixel.color($iOffset + $x2 + 2) = $g
$tPixel.color($iOffset + $x2 + 3) = $r
If $bytesPerPixel = 4 Then $tPixel.color($iOffset + $x2 + 4) = $tBuffer.color($iOffset + $x1 + 4)
Next
ConsoleWrite(Round($y / (($iH - 1) * $bytesPerPixel) * 100, 0) & "%" & @CRLF)
Next
;TGA image is stored bottom up in file. Need to flip it.
If BitAND($tTGAHeader.imageDescriptor, 0x30) <> 0x20 Then _GDIPlus_ImageRotateFlip($hBitmap, 6)
$tBuffer = 0
Return $hBitmap
EndFunc ;==>_GDIPlus_TGAImageLoadFromFile
Global $sFile = FileOpenDialog("Select a TGA file", "", "TGA image(*.tga)")
If @error Then Exit
_GDIPlus_Startup()
Global $hImage = _GDIPlus_TGAImageLoadFromFile($sFile)
If @error Then
ConsoleWrite(@error & @CRLF)
_GDIPlus_Shutdown()
Exit
EndIf
_GDIPlus_ImageSaveToFile($hImage, @ScriptDir & "\Converted.png")
ShellExecute(@ScriptDir & "\Converted.png")
Global $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage)
Global $hGui = GUICreate("", $iW, $iH)
GUISetState()
Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, 0, 0, $iW, $iH)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
Exit
Case $GUI_EVENT_RESTORE
; to redraw the Bitmap
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, 0, 0, $iW, $iH)
EndSwitch
WEnd
Alles anzeigen
Wenn ein TGA Bild transparent ist, dann sollte die Transparenz erhalten bleiben.
Du kannst ja mal in der Original C++ Source reinschauen, wie es dort gelöst wurde, falls noch nicht getan. -> https://github.com/HackerPoet/Chaos-Equations
Ich weiß nicht, ob ich dazu komme den C++ Code zu analysieren...
Sodele, ich habe auch noch ein bissl recherchiert und diese sollte die Lösung sein:
;Coded by UEZ build 2019-08-08 beta
#AutoIt3Wrapper_Res_HiDpi=Y
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware
Global Const $WM_DPICHANGED = 0x02E0, $WM_GETDPISCALEDSIZE = 0x02E4
Global $dpiScaledX, $dpiScaledY, $aCtrlFS[5][2], $hGUI, $hGUI_child, $g_iDPI_ratio2
Example1()
Func Example1() ;thanks to alpines for the main GUI layout
_WinAPI_SetDPIAwareness()
Local $iDPI
If @OSBuild < 14393 Then
$iDPI = _GDIPlus_GraphicsGetDPIRatio()
Else
Local $hGUI_dummy = GUICreate("", 1, 1)
$iDPI = _WinAPI_GetDpiForWindow($hGUI_dummy)
GUIDelete($hGUI_dummy)
EndIf
Local $iDPI_ratio = $iDPI / 96
$g_iDPI_ratio2 = 96 / $iDPI
$hGUI = GUICreate("Example 1", 314 * $iDPI_ratio, 130 * $iDPI_ratio, -1, 10)
GUISetFont(12 * $iDPI_ratio, 400, 0, "Times New Roman")
$aCtrlFS[0][0] = GUICtrlCreateLabel("Label1", 16 * $iDPI_ratio, 16 * $iDPI_ratio, 40 * $iDPI_ratio, 21 * $iDPI_ratio)
$aCtrlFS[0][1] = 10
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$aCtrlFS[1][0] = GUICtrlCreateLabel("Label2", 64 * $iDPI_ratio, 16 * $iDPI_ratio, 40 * $iDPI_ratio, 21 * $iDPI_ratio)
$aCtrlFS[1][1] = 10
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$aCtrlFS[2][0] = GUICtrlCreateLabel("Label3", 112 * $iDPI_ratio, 16 * $iDPI_ratio, 40 * $iDPI_ratio, 21 * $iDPI_ratio)
$aCtrlFS[2][1] = 10
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$aCtrlFS[3][0] = GUICtrlCreateInput("Input1", 160 * $iDPI_ratio, 16 * $iDPI_ratio, 137 * $iDPI_ratio, 22 * $iDPI_ratio)
$aCtrlFS[3][1] = 10
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$aCtrlFS[4][0] = GUICtrlCreateButton("Close", 16 * $iDPI_ratio, 48 * $iDPI_ratio, 283 * $iDPI_ratio, 65 * $iDPI_ratio)
$aCtrlFS[4][1] = 16
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$hGUI_child = GUICreate("Child", 320 * $iDPI_ratio, 260 * $iDPI_ratio, -1, -1, -1, -1, $hGUI)
GUISetBkColor(0xFFFFFF)
Local $iLable_child = GUICtrlCreateLabel("Label1", 16, 16, 288 * $iDPI_ratio, 168 * $iDPI_ratio)
GUICtrlSetFont(-1, 65, 400, 0, "Times New Roman", 5)
Local $iPic_child = GUICtrlCreatePic("c:\Program Files (x86)\AutoIt3\Examples\GUI\Merlin.gif", 0, 160, 68, 71)
ResizeFont($hGUI)
GUISetState(@SW_SHOW, $hGUI)
GUISetState(@SW_SHOW, $hGUI_child)
GUIRegisterMsg($WM_DPICHANGED, "WM_DPICHANGED") ;requires Win 8.1+ / Server 2012 R2+
;~ GUIRegisterMsg($WM_GETDPISCALEDSIZE, "WM_GETDPISCALEDSIZE")
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $aCtrlFS[4][0]
GUIDelete($hGUI)
ExitLoop
EndSwitch
WEnd
EndFunc ;==>Example1
Func ResizeFont($hWnd)
If $hWnd = $hGUI Then
Local $iDPI = _WinAPI_GetDpiForWindow($hWnd)
Local $i, $dpi_ratio = $iDPI / 96
For $i = 0 To UBound($aCtrlFS) - 1
GUICtrlSetFont($aCtrlFS[$i][0], $aCtrlFS[$i][1] * $dpi_ratio * $g_iDPI_ratio2, 400, 0, "Times New Roman", 5)
Next
EndIf
EndFunc
Func _WinAPI_FindWindowEx($hWndParent, $hWndChildAfter = 0, $sClassName = "", $sWindowName = "")
Local $aResult = DllCall("user32.dll", "hwnd", "FindWindowEx", "hwnd", $hWndParent, "hwnd", $hWndChildAfter, "wstr", $sClassName, "wstr", $sWindowName)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc
Func _WinAPI_GetDpiForWindow($hWnd)
Local $aResult = DllCall("user32.dll", "uint", "GetDpiForWindow", "hwnd", $hWnd) ;requires Win10 v1607+ / no server support
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc
Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
_GDIPlus_Startup()
Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
If @error Then Return SetError(1, @extended, 0)
Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
If @error Then Return SetError(2, @extended, 0)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_Shutdown()
Return $aResult[2]
EndFunc ;==>_GDIPlus_GraphicsGetDPIRatio
Func WM_GETDPISCALEDSIZE($hWnd, $iMsg, $wParam, $lParam)
Local $tSize = DllStructCreate($tagSIZE, $lParam)
Return True
EndFunc
Func WM_DPICHANGED($hWnd, $iMsg, $wParam, $lParam)
Local $tRECT = DllStructCreate($tagRECT, $lParam)
Local $iX = $tRECT.left, $iY = $tRECT.top, $iW = $tRECT.right - $iX, $iH = $tRECT.bottom - $iY
;requires Win10 v1607+ / no server support
DllCall("user32.dll", "bool", "AdjustWindowRectExForDpi", "struct*", $tRECT, "dword", BitOR($WS_BORDER, $WS_CAPTION, $WS_CLIPSIBLINGS, $WS_GROUP, $WS_POPUP, $WS_SYSMENU, $WS_VISIBLE), "bool", False, "dword", $WS_EX_WINDOWEDGE, "uint", _WinAPI_HiWord($wParam))
_WinAPI_SetWindowPos($hWnd, 0, $iX, $iY, $iW, $iH, BitOR($SWP_NOZORDER, $SWP_NOACTIVATE))
ResizeFont($hWnd)
$tRECT = 0
Return 1
EndFunc ;==>WM_DPICHANGED
Func _WinAPI_SetDPIAwareness($hGUI = 0)
Switch @OSBuild
Case 6000 To 9199
If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0) ;requires Vista+ / Server 2008+
Return 1
Case 9200 To 13999
_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(2, 0, 0)
Return 1
Case @OSBuild > 13999
#cs
Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
#ce
_WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI, 1)
If @error Then Return SetError(3, @error, 0)
Return 1
EndSwitch
Return -1
EndFunc ;==>_WinAPI_SetDPIAwareness
Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
Local $aResult = DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware) ;requires Win 8.1+ / Server 2012 R2+
If @error Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwareness
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 1)
$DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
$iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
Switch $iMode
Case 1
Local $hDC = _WinAPI_GetDC($hGUI)
Local $aResult1 = DllCall("user32.dll", "int", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) ;requires Win10 v1803+ / Server 2016+
If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
_WinAPI_ReleaseDC(0, $hDC)
;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
Case 2
;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) ;requires Win10 v1703+ / Server 2016+
If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
Case 3
Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
Local $aResult32 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) ;requires Win10 v1607+ / no server support
If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
EndSwitch
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext
Alles anzeigen
Ich benutze dieses Manifest, welches von AutoIt3Wrapper.exe generiert und in die Exe hinzugefügt wird.
Hier die relevanten Zeilen, so ab 2530:
...
$TempFile2 = __TempFile($TempDir, "RHManifest", "", ".txt")
Local $hTempFile2 = FileOpen($TempFile2, 2)
FileWriteLine($hTempFile2, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>')
FileWriteLine($hTempFile2, '<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >')
FileWriteLine($hTempFile2, '')
If $INP_Res_requestedExecutionLevel = "" Then
$INP_Res_requestedExecutionLevel = "asInvoker"
Else
Write_RC_Console_Msg("Setting Program ExecutionLevel Manifest information to " & $INP_Res_requestedExecutionLevel, "", "...", 0)
EndIf
If $INP_Res_requestedExecutionLevel <> "None" Then
FileWriteLine($hTempFile2, ' <!-- Identify the application security requirements. -->')
FileWriteLine($hTempFile2, ' <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">')
FileWriteLine($hTempFile2, ' <security>')
FileWriteLine($hTempFile2, ' <requestedPrivileges>')
FileWriteLine($hTempFile2, ' <requestedExecutionLevel')
FileWriteLine($hTempFile2, ' level="' & $INP_Res_requestedExecutionLevel & '"')
FileWriteLine($hTempFile2, ' uiAccess="false"')
FileWriteLine($hTempFile2, ' />')
FileWriteLine($hTempFile2, ' </requestedPrivileges>')
FileWriteLine($hTempFile2, ' </security>')
FileWriteLine($hTempFile2, ' </trustInfo>')
FileWriteLine($hTempFile2, '')
EndIf
FileWriteLine($hTempFile2, ' <!-- Identify the application dependencies. -->')
FileWriteLine($hTempFile2, ' <dependency>')
FileWriteLine($hTempFile2, ' <dependentAssembly>')
FileWriteLine($hTempFile2, ' <assemblyIdentity')
FileWriteLine($hTempFile2, ' type="win32"')
FileWriteLine($hTempFile2, ' name="Microsoft.Windows.Common-Controls"')
FileWriteLine($hTempFile2, ' version="6.0.0.0"')
FileWriteLine($hTempFile2, ' language="*"')
FileWriteLine($hTempFile2, ' processorArchitecture="*"')
FileWriteLine($hTempFile2, ' publicKeyToken="6595b64144ccf1df"')
FileWriteLine($hTempFile2, ' />')
FileWriteLine($hTempFile2, ' </dependentAssembly>')
FileWriteLine($hTempFile2, ' </dependency>')
FileWriteLine($hTempFile2, '')
If $INP_RES_HiDpi <> "n" Then
;~ If $INP_RES_HiDpi <> "y" Then
Write_RC_Console_Msg("Setting DPI awareness Manifest information...", "", "...", 0)
FileWriteLine($hTempFile2, ' <asmv3:application>')
FileWriteLine($hTempFile2, ' <asmv3:windowsSettings xmlns="https://schemas.microsoft.com/SMI/2016/WindowsSettings">')
FileWriteLine($hTempFile2, ' <dpiAwareness>PerMonitorV2</dpiAwareness>')
FileWriteLine($hTempFile2, ' </asmv3:windowsSettings>')
FileWriteLine($hTempFile2, ' <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">')
FileWriteLine($hTempFile2, ' <dpiAware>true/pm</dpiAware>')
FileWriteLine($hTempFile2, ' </asmv3:windowsSettings>')
FileWriteLine($hTempFile2, ' <asmv3:windowsSettings xmlns="https://schemas.microsoft.com/SMI/2017/WindowsSettings">')
FileWriteLine($hTempFile2, ' <gdiScaling>true</gdiScaling>')
FileWriteLine($hTempFile2, ' </asmv3:windowsSettings>')
;~ Else
;~ Write_RC_Console_Msg("Setting DPI awareness Manifest information to true", "", "...", 0)
;~ FileWriteLine($hTempFile2, ' <dpiAware>true</dpiAware>')
;~ EndIf
;~ FileWriteLine($hTempFile2, ' <asmv3:windowsSettings>')
;~ FileWriteLine($hTempFile2, ' <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>')
;~ FileWriteLine($hTempFile2, ' <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>')
;~ FileWriteLine($hTempFile2, ' <gdiScaling xmlns="http://schemas.microsoft.com/SMI/2017/WindowsSettings">true</gdiScaling>')
;~ FileWriteLine($hTempFile2, ' </asmv3:windowsSettings>')
FileWriteLine($hTempFile2, ' </asmv3:application>')
FileWriteLine($hTempFile2, '')
EndIf
; ----- reverted this change as it is giving some issues. Needs investigation
;~ If $INP_RES_HiDpi <> "n" Then
;~ FileWriteLine($hTempFile2, ' <application xmlns="urn:schemas-microsoft-com:asm.v3"> ')
;~ FileWriteLine($hTempFile2, ' <windowsSettings>')
;~ FileWriteLine($hTempFile2, ' <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>')
;~ FileWriteLine($hTempFile2, ' <gdiScaling xmlns="http://schemas.microsoft.com/SMI/2017/WindowsSettings">true</gdiScaling>')
;~ FileWriteLine($hTempFile2, ' <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>')
;~ If $INP_RES_HiDpi <> "y" Then
;~ Write_RC_Console_Msg("Setting DPI awareness Manifest information to true/PM", "", "...", 0)
;~ FileWriteLine($hTempFile2, ' <dpiAware>true/PM</dpiAware>')
;~ Else
;~ Write_RC_Console_Msg("Setting DPI awareness Manifest information to true", "", "...", 0)
;~ FileWriteLine($hTempFile2, ' <dpiAware>true</dpiAware>')
;~ EndIf
;~ FileWriteLine($hTempFile2, ' </windowsSettings>')
;~ FileWriteLine($hTempFile2, ' </application>')
;~ FileWriteLine($hTempFile2, '')
;~ EndIf
...
Alles anzeigen
Kann jemand bitte testen, ob jetzt die Test GUI DPI kompatible ist? Die Child GUI ist definitiv nicht DPI "aware", aber die Haupt GUI sollte es sein.
Danke.
Theoretisch kannst du jederzeit dich anmelden, aber um die Bonus Fragen zu tippen, spätestens bis nächsten Freitag, glaube ich. Kann am Ende eventuell entscheidend sein.
Du kannst auch jetzt die nächsten paar Spieltage tippen. Ist am Anfang ehe raten... ![]()
Halli Hallo,
es ist wieder soweit die nächste Runde einzuläuten.
Wer mitmachen möchte, einfach auf autoit-bl kostenlos Mitglied werden und lostippen.
Btw, es wäre nett, wenn der User Name dem aus diesem Forum identisch ist, um einfach einen Bezug zu haben. DANKE.
Die Teilnehmer der letzten Saison sind nicht gelöscht und können direkt loslegen, falls gewollt.
Happy Tipping.
Edit:
Gewonnen hat Tweaky. Herzlichen Glückwunsch![]()
Bitnugger Wunderschönes Gesicht ![]()
Hallo eukalyptus,
schöne dich wieder hier zu sehen! ![]()
Das Ergebnis ist durchaus brauchbar. Ich habe leider nicht so viele Bilder mit Gesichtern, werde aber mal danach googeln.
Könnt ihr dies bitte testen?
;Coded by UEZ build 2019-06-21 beta
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPISysWin.au3>
_GDIPlus_Startup()
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE
Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware
; enum _MONITOR_DPI_TYPE
Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI
Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI
Global $aDPI[2] = [1, 1], $dpiScaledX, $dpiScaledY
_WinAPI_SetDPIAwareness()
If @OSBuild < 9200 Then
$aDPI = _GDIPlus_GraphicsGetDPIRatio()
Else
If @OSBuild < 10000 Then $aDPI = _WinAPI_GetDpiForMonitor()
EndIf
Global Const $WM_DPICHANGED = 0x02E0
Global $iLabel1, $iLabel2, $iLabel3, $iInput, $iButton
Example1()
_GDIPlus_Shutdown()
Func Example1() ;example by alpines
Local Const $GUI_CLIENT_WIDTH = 314
Local Const $GUI_CLIENT_HEIGHT = 130
Local $hGUI = GUICreate("Beispiel 1", $GUI_CLIENT_WIDTH, $GUI_CLIENT_HEIGHT, -1, -1)
GUISetFont(12 * $aDPI[1], 400, 0, "Times New Roman")
$iLabel1 = GUICtrlCreateLabel("Label1", 16, 16, 36, 21)
GUICtrlSetFont(-1, 10 * $aDPI[1], 400, 0, "Times New Roman", 5)
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$iLabel2 = GUICtrlCreateLabel("Label2", 64, 16, 36, 21)
GUICtrlSetFont(-1, 10 * $aDPI[1], 400, 0, "Times New Roman", 5)
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$iLabel3 = GUICtrlCreateLabel("Label3", 112, 16, 36, 21)
GUICtrlSetFont(-1, 10 * $aDPI[1], 400, 0, "Times New Roman", 5)
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$iInput = GUICtrlCreateInput("Input1", 160, 16, 137, 21)
GUICtrlSetFont(-1, 10 * $aDPI[1], 400, 0, "Times New Roman", 5)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
$iButton = GUICtrlCreateButton("Schließen", 16, 48, 283, 65)
GUICtrlSetFont(-1, 10 * $aDPI[1], 400, 0, "Times New Roman", 5)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
GUISetState(@SW_SHOW, $hGUI)
GUIRegisterMsg($WM_DPICHANGED, "WM_DPICHANGED")
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $iButton
GUIDelete($hGUI)
ExitLoop
EndSwitch
WEnd
EndFunc ;==>Example1
Func WM_DPICHANGED($hWnd, $iMsg, $wParam, $lParam)
Local $tRECT = DllStructCreate($tagRECT, $lParam)
Local $iDPIX = _WinAPI_LoWord($wParam), $iDPIY = _WinAPI_HiWord($wParam)
$dpiScaledX = $iDPIX / 96
$dpiScaledY = $iDPIY / 96
Local $iW = $tRECT.right - $tRECT.left, $iH = $tRECT.bottom - $tRECT.top
Local $aWPos = WinGetPos($hWnd)
_WinAPI_SetWindowPos($hWnd, 0, $aWPos[0], $aWPos[1], $iW, $iH, BitOR($SWP_NOZORDER, $SWP_NOACTIVATE))
UpdateControlFontSize()
EndFunc
Func UpdateControlFontSize()
GUICtrlSetFont($iLabel1, 10 * $dpiScaledX, 400, 0, "Times New Roman", 5)
GUICtrlSetFont($iLabel2, 10 * $dpiScaledX, 400, 0, "Times New Roman", 5)
GUICtrlSetFont($iLabel3, 10 * $dpiScaledX, 400, 0, "Times New Roman", 5)
GUICtrlSetFont($iInput, 10 * $dpiScaledX, 400, 0, "Times New Roman", 5)
GUICtrlSetFont($iButton, 10 * $dpiScaledX, 400, 0, "Times New Roman", 5)
EndFunc
Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
If @error Then Return SetError(1, @extended, 0)
Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
If @error Then Return SetError(2, @extended, 0)
Local $iDPI = $aResult[2]
_GDIPlus_GraphicsDispose($hGfx)
Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
Return $aResults
EndFunc ;==>_GDIPlus_GraphicsGetDPIRatio
Func _WinAPI_GetDpiForMonitor($dpiType = $MDT_DEFAULT, $iDPIDef = 96)
Local $aMonitors = _WinAPI_EnumDisplayMonitors()
Local $x, $y
Local $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $aMonitors[1][0], "int", $dpiType, "uint*", $x, "uint*", $y)
If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0)
Local $aDPI[2] = [$iDPIDef / $aRet[3], $aRet[3] / $iDPIDef]
Return $aDPI
EndFunc ;==>_WinAPI_GetDpiForMonitor
Func _WinAPI_SetDPIAwareness($hGUI = 0)
Switch @OSBuild
Case 6000 To 9199
If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0)
Return 1
Case 9200 To 13999
_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
If @error Then Return SetError(1, 0, 0)
Return 1
Case @OSBuild > 13999
#cs
Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
#ce
_WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAware, $hGUI)
If @error Then Return SetError(3, @error, 0)
Return 1
EndSwitch
Return -1
EndFunc ;==>_WinAPI_SetDPIAwareness
Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware)
If @error Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwareness
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 3) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
$DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
$iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode
Switch $iMode
Case 1
Local $hDC = _WinAPI_GetDC($hGUI)
Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC)
If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0)
_WinAPI_ReleaseDC(0, $hDC)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext)
If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0)
Case 2
;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI)
If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext)
If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0)
Case 3
Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext")
If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0)
Local $aResult32 = DllCall("user32.dll", "ptr", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0])
If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0)
Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext)
If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0)
EndSwitch
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext
Alles anzeigen
Keine Ahnung, wie das Skript unter Win7 / Win 8 läuft...
Mein Screenshooter funktioniert auch nicht richtig, wenn DPI Awareness nicht aktiviert wurde. Dann kannst du nicht richtig den Bereich markieren.
[Blockierte Grafik: https://i.ibb.co/pwWdr3M/DPI-Awareness.png]
Nun ja, das hängt davon ab, wie du deine GUI dargestellt haben willst. Ohne DPI Awareness wird die GUI entsprechend vergrößert und die GUI erscheint "blurry". So sieht es zumindest auf meinem Win10 aus, wenn ich nur eine von drei Monitoren auf 125% stelle.
Die GUI sieht auf den anderen zwei Monitoren ok aus, aber sobald ich die GUI auf den 3. Monitor verschiebe, wird die GUI vergrößert und unscharf dargestellt. Kann auch sein, dass die GUI zu groß wird.
Monitor 3 habe ich z.B. auf 150% gestellt und ohne DPI Awareness passt eine Applikation nicht mehr in den sichtbaren Bereich - mit DPI Awareness schon.
Artikel: https://docs.microsoft.com/en-us/windows/…ment-on-windows
Kannst du das hier mal bitte testen?
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <WinAPIGdiDC.au3>
_GDIPlus_Startup()
; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx
Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE
; enum _MONITOR_DPI_TYPE
Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI
Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI
Global $aDPI[2] = [1, 1]
_WinAPI_SetDPIAwareness()
;~ If @OSBuild < 9200 Then
;~ $aDPI = _GDIPlus_GraphicsGetDPIRatio()
;~ Else
;~ $aDPI = _WinAPI_GetDpiForMonitor()
;~ EndIf
Example1()
_GDIPlus_Shutdown()
Func Example1()
Local Const $GUI_CLIENT_WIDTH = 314
Local Const $GUI_CLIENT_HEIGHT = 130
Local $hGUI = GUICreate("Beispiel 1", $GUI_CLIENT_WIDTH, $GUI_CLIENT_HEIGHT, -1, -1)
GUISetFont(12 * $aDPI[0], 400, 0, "Times New Roman")
Local $hLabel1 = GUICtrlCreateLabel("Label1", 16, 16, 36, 21)
GUICtrlSetFont(-1, 10 * $aDPI[0], 400, 0, "Times New Roman", 5)
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
Local $hLabel2 = GUICtrlCreateLabel("Label2", 64, 16, 36, 21)
GUICtrlSetFont(-1, 10 * $aDPI[0], 400, 0, "Times New Roman", 5)
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
Local $hLabel3 = GUICtrlCreateLabel("Label3", 112, 16, 36, 21)
GUICtrlSetFont(-1, 10 * $aDPI[0], 400, 0, "Times New Roman", 5)
GUICtrlSetBkColor(-1, 0x3399FF)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
Local $hInput = GUICtrlCreateInput("Input1", 160, 16, 137, 21)
GUICtrlSetFont(-1, 10 * $aDPI[0], 400, 0, "Times New Roman", 5)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
Local $hButton = GUICtrlCreateButton("Schließen", 16, 48, 283, 65)
GUICtrlSetFont(-1, 10 * $aDPI[0], 400, 0, "Times New Roman", 5)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)
GUISetState(@SW_SHOW, $hGUI)
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $hButton
GUIDelete($hGUI)
ExitLoop
EndSwitch
WEnd
EndFunc
Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96)
Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0)
If @error Then Return SetError(1, @extended, 0)
Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0)
If @error Then Return SetError(2, @extended, 0)
Local $iDPI = $aResult[2]
_GDIPlus_GraphicsDispose($hGfx)
Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef]
Return $aResults
EndFunc ;==>_GDIPlus_GraphicsGetDPIRatio
Func _WinAPI_GetDpiForMonitor($dpiType = $MDT_DEFAULT, $iDPIDef = 96)
Local $aMonitors = _WinAPI_EnumDisplayMonitors()
Local $x, $y
Local $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $aMonitors[1][0], "int", $dpiType, "uint*", $x, "uint*", $y)
If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0)
Local $aDPI[2] = [$iDPIDef / $aRet[3], $aRet[3] / $iDPIDef]
Return $aDPI
EndFunc ;==>_WinAPI_GetDpiForMonitor
Func _WinAPI_SetDPIAwareness($hGUI = 0)
Switch @OSBuild
Case 6000 To 9199
DllCall("user32.dll", "bool", "SetProcessDPIAware")
Case 9200 To 13999
_WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE)
Case 14000 To 30000
#cs
Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)),
Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)),
Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)),
Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)),
Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5))
#ce
_WinAPI_SetProcessDpiAwarenessContext(-3, $hGUI)
EndSwitch
EndFunc
Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness
DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware)
If @error Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwareness
Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext, $hGUI = 0) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext
Local $hDC = _WinAPI_GetDC($hGUI)
Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC)
If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle())
Local $aResult2 = DllCall("user32.dll", "ptr", "GetWindowDpiAwarenessContext", "ptr", $hGUI)
Local $aResult3 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext")
Local $aResult4 = DllCall("user32.dll", "int", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult2[1])
_WinAPI_ReleaseDC(0, $hDC)
$DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext
Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext)
If @error Or Not $aResult[0] Then Return SetError(1, 0, 0)
Return 1
EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext
Alles anzeigen