Fehler in GDIPlus.au3

  • Hallo Leute,

    in meinem Folgenden Skript wird mir ein merkwürdiger Fehler in der GDIPlus.au3 von AutoIt gemeldet. Das Skript soll jede Minute den Hintergrund ändern und dort z.B. die Uhrzeit anzeigen.
    Nun kommt aber immer dieser Fehler

    [autoit]

    "C:\Program Files\AutoIt3\Include\GDIPlus.au3" (1661) : ==> Subscript used with non-Array variable.:
    Local $aResult = _GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)
    Local $aResult = _GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo^ ERROR
    ->21:09:00 AutoIt3.exe ended.rc:1
    >Exit code: 1 Time: 33.472

    [/autoit]
    Spoiler anzeigen
    [autoit]

    #include <Date.au3>
    #include <GDIPlus.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sTime = _NowTime(4)

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(20)
    If $sTime <> _NowTime(4) Then
    $sTime = _NowTime(4)
    _New_Background($sTime)
    ;MsgBox(0, "", "Change")
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _New_Background($Time)
    Local $hGUI = GUICreate("BG-Dummy",@DesktopWidth,@DesktopHeight)
    Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics(@DesktopWidth,@DesktopHeight,$hGraphic)
    Local $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hRed = _GDIPlus_BrushCreateSolid(0x99FF0000)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsFillEllipse($hBuffer,(@DesktopWidth / 2) - 200, (@DesktopHeight / 2) - 100,200,100,$hRed)
    Local $iTextWidth = _GetTextLabelWidth($Time,"Arial",10)
    ConsoleWrite($iTextWidth & @CRLF)
    _GDIPlus_GraphicsDrawString($hBuffer,$Time,(@DesktopWidth / 2) - ($iTextWidth / 2),(@DesktopHeight / 2) - 5,"Arial",10,0x0001)
    _GDIPlus_GraphicsDrawImage($hGraphic,$hBitmap,0,0)
    ;_GDIPlus_ImageSaveToFile($hBitmap,@TempDir & "\Image_" & StringReplace($Time,":","_") & ".jpg")
    RegWrite("HKEY_CURRENT_USER\Control Panel\Desktop", "WallpaperStyle", "REG_SZ", "0")
    RegWrite("HKEY_CURRENT_USER\Control Panel\Desktop", "TileWallpaper", "REG_SZ", "0")
    DllCall("user32.dll", "int", "SystemParametersInfo","uint",20,"uint",0,"str",$hBitmap,"uint",3)

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_New_Background

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetTextLabelWidth($s_WinText, $s_TextFont, $i_FontSize, $i_FontWeight = -1)
    Local Const $DEFAULT_CHARSET = 0 ; ANSI character set
    Local Const $OUT_CHARACTER_PRECIS = 2
    Local Const $CLIP_DEFAULT_PRECIS = 0
    Local Const $PROOF_QUALITY = 2
    Local Const $FIXED_PITCH = 1
    Local Const $RGN_XOR = 3
    Local Const $LOGPIXELSY = 90
    Local Const $dUser32 = DllOpen("user32.dll"), $dGDI32 = DllOpen("gdi32.dll"), $dKERN32 = DllOpen("kernel32.dll")
    $h_WinTitle = "Get Label Width"
    If $i_FontWeight = "" Or $i_FontWeight = -1 Then $i_FontWeight = 600 ; default Font weight
    Local $h_GUI = GUICreate($h_WinTitle, 10, 10, -100, -100, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW)
    Local $hDC = DllCall($dUser32, "int", "GetDC", "hwnd", $h_GUI)
    Local $intDeviceCap = DllCall($dGDI32, "long", "GetDeviceCaps", "int", $hDC[0], "long", $LOGPIXELSY)
    $intDeviceCap = $intDeviceCap[0]
    Local $intFontHeight = DllCall($dKERN32, "long", "MulDiv", "long", $i_FontSize, "long", $intDeviceCap, "long", 72)
    $intFontHeight = -$intFontHeight[0]
    Local $hMyFont = DllCall($dGDI32, "hwnd", "CreateFont", "int", $intFontHeight, "int", 0, "int", 0, "int", 0, "int", $i_FontWeight, "int", 0, "int", 0, "int", 0, "int", $DEFAULT_CHARSET, "int", $OUT_CHARACTER_PRECIS, "int", $CLIP_DEFAULT_PRECIS, "int", $PROOF_QUALITY, "int", $FIXED_PITCH, "str", $s_TextFont)
    DllCall($dGDI32, "hwnd", "SelectObject", "int", $hDC[0], "hwnd", $hMyFont[0])
    Local $res = DllStructCreate("int;int")
    Local $ret = DllCall($dGDI32, "int", "GetTextExtentPoint32", "int", $hDC[0], "str", $s_WinText, "long", StringLen($s_WinText), "ptr", DllStructGetPtr($res))
    Local $intLabelWidth = DllStructGetData($res, 1)
    GUIDelete($h_GUI)
    Return $intLabelWidth
    EndFunc ;==>_GetTextLabelWidth

    [/autoit]

    Könnte mir jemand erklären wieso der Fehler in der GDIPlus.au3 liegt und wie man ihn behebt?

    Vielen Dank :)

  • Bitte erzähl mir nicht, dass du darauf nicht selbst mit ein wenig mehr Aufmerksamkeit gekommen wärst :rolleyes: .

    Spoiler anzeigen
    [autoit]

    #include <Date.au3>
    #include <GDIPlus.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sTime = _NowTime(4)

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(20)
    If $sTime <> _NowTime(4) Then
    $sTime = _NowTime(4)
    _New_Background($sTime)
    ;MsgBox(0, "", "Change")
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _New_Background($Time)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPLUS_STARTUP() ; <------ !!!

    [/autoit] [autoit][/autoit] [autoit]

    Local $hGUI = GUICreate("BG-Dummy",@DesktopWidth,@DesktopHeight)
    Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics(@DesktopWidth,@DesktopHeight,$hGraphic)
    Local $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hRed = _GDIPlus_BrushCreateSolid(0x99FF0000)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsFillEllipse($hBuffer,(@DesktopWidth / 2) - 200, (@DesktopHeight / 2) - 100,200,100,$hRed)
    Local $iTextWidth = _GetTextLabelWidth($Time,"Arial",10)
    ConsoleWrite($iTextWidth & @CRLF)
    _GDIPlus_GraphicsDrawString($hBuffer,$Time,(@DesktopWidth / 2) - ($iTextWidth / 2),(@DesktopHeight / 2) - 5,"Arial",10,0x0001)
    _GDIPlus_GraphicsDrawImage($hGraphic,$hBitmap,0,0)
    ;_GDIPlus_ImageSaveToFile($hBitmap,@TempDir & "\Image_" & StringReplace($Time,":","_") & ".jpg")
    RegWrite("HKEY_CURRENT_USER\Control Panel\Desktop", "WallpaperStyle", "REG_SZ", "0")
    RegWrite("HKEY_CURRENT_USER\Control Panel\Desktop", "TileWallpaper", "REG_SZ", "0")
    DllCall("user32.dll", "int", "SystemParametersInfo","uint",20,"uint",0,"str",$hBitmap,"uint",3)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPLUS_SHUTDOWN() ; <------ !!!

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc ;==>_New_Background

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetTextLabelWidth($s_WinText, $s_TextFont, $i_FontSize, $i_FontWeight = -1)
    Local Const $DEFAULT_CHARSET = 0 ; ANSI character set
    Local Const $OUT_CHARACTER_PRECIS = 2
    Local Const $CLIP_DEFAULT_PRECIS = 0
    Local Const $PROOF_QUALITY = 2
    Local Const $FIXED_PITCH = 1
    Local Const $RGN_XOR = 3
    Local Const $LOGPIXELSY = 90
    Local Const $dUser32 = DllOpen("user32.dll"), $dGDI32 = DllOpen("gdi32.dll"), $dKERN32 = DllOpen("kernel32.dll")
    $h_WinTitle = "Get Label Width"
    If $i_FontWeight = "" Or $i_FontWeight = -1 Then $i_FontWeight = 600 ; default Font weight
    Local $h_GUI = GUICreate($h_WinTitle, 10, 10, -100, -100, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW)
    Local $hDC = DllCall($dUser32, "int", "GetDC", "hwnd", $h_GUI)
    Local $intDeviceCap = DllCall($dGDI32, "long", "GetDeviceCaps", "int", $hDC[0], "long", $LOGPIXELSY)
    $intDeviceCap = $intDeviceCap[0]
    Local $intFontHeight = DllCall($dKERN32, "long", "MulDiv", "long", $i_FontSize, "long", $intDeviceCap, "long", 72)
    $intFontHeight = -$intFontHeight[0]
    Local $hMyFont = DllCall($dGDI32, "hwnd", "CreateFont", "int", $intFontHeight, "int", 0, "int", 0, "int", 0, "int", $i_FontWeight, "int", 0, "int", 0, "int", 0, "int", $DEFAULT_CHARSET, "int", $OUT_CHARACTER_PRECIS, "int", $CLIP_DEFAULT_PRECIS, "int", $PROOF_QUALITY, "int", $FIXED_PITCH, "str", $s_TextFont)
    DllCall($dGDI32, "hwnd", "SelectObject", "int", $hDC[0], "hwnd", $hMyFont[0])
    Local $res = DllStructCreate("int;int")
    Local $ret = DllCall($dGDI32, "int", "GetTextExtentPoint32", "int", $hDC[0], "str", $s_WinText, "long", StringLen($s_WinText), "ptr", DllStructGetPtr($res))
    Local $intLabelWidth = DllStructGetData($res, 1)
    GUIDelete($h_GUI)
    Return $intLabelWidth
    EndFunc ;==>_GetTextLabelWidth

    [/autoit]
  • Wie kommst du auf das schmale Brett, dass der Fehler in der GDI+ liegt? :rofl:
    Wenn du Schei.. übergibst kann die Funktion auch nur Schei.. liefern. :whistling:


    Oder man vergisst GDI+ zu starten :rofl:

    There's a joke that C has the speed and efficieny of assembly language combined with readability of....assembly language. In other words, it's just a glorified assembly language. - Teh Interwebz

    C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, you blow off your whole leg. - Bjarne Stroustrup
    Genie zu sein, bedeutet für mich, alles zu tun, was ich will. - Klaus Kinski

  • BugFix Das ist ein Fehler innerhalb der Funktion _GDIPlus_GraphicsDrawString. Die ruft intern einfach nur _GDIPlus_GraphicsDrawStringEx auf und generiert dazu noch eine RECTF Struktur mit _GDIPlus_GraphicsMeasureString. Die Funktion gibt kein Array zurück, wenn sie fehlschlägt (er hat vergessen die Dll per _Startup Funktion zu öffnen und in eine globale Variable schreiben zu lassen -> Funktion schlägt fehl).
    Da wohl niemand daran gedacht hat für diesen Fall Errorhandling einzubauen, um das ganze wirklich idiotensicher zu machen, beschwert sich AutoIt halt über das Array das keins ist. ^^

  • Zitat

    Da wohl niemand daran gedacht hat für diesen Fall Errorhandling einzubauen, um das ganze wirklich idiotensicher zu machen, beschwert sich AutoIt halt über das Array das keins ist.

    Ein Hoch auf die Programmierkunst!
    Genau wegen dieser "Fehler" werden für die einfachsten (Win-API)-Funktionen Errorhandlings eingebaut, und zwar dermassen viele, dass bei den meisten Funktionen das Errorhandling bei weitem das Maß überschreitet bzw. die Ausführungsgeschwindigkeit extrem verlangsamt!
    Wenn ein simpler "Sin()" in C++ bis zu 5x länger dauert wie der Inline-ASM-Code (Aufgrund des Errorhandlings ! ) dann kann man sich ansatzweise Vorstellen wie viel schneller u.a. GDI wäre, wenn man auf die "Fehler"-Abfragen weitgehend verzichten könnte....
    Erschwerend kommt noch dazu, dass die "Programmierer" nicht mal in der Lage sind, die "Fehler" auszuwerten, s. u.a. diesen Thread :huh:

    Genau aus diesem Grund weigere ich mich mittlerweile, sog. UDF´s zu publizieren!
    Die "Anwender" dieser Funktionen gehen selbstverständlich davon aus, dass es weder nötig ist, Funktionsbeschreibungen zu lesen, noch auf die Syntax oder die Datentypen zu achten....
    Um alle diese "Fehler" (wohlgemerkt nicht die der Funktion, sondern der ignoranten oder faulen Anwender) abzufangen, muss man einen simplen 20-Zeiler auf 100 Zeilen "bloaten".
    Wie hier im Thread gezeigt, hilft auch das nicht, wenn die Errormessages nicht in einer Messagebox angezeigt werden. Simples SetError() ist somit völlig überflüssig ;(
    Ein Hoch auf die Programmierkunst!