Geschriebenes mit _WinAPI_DrawText wieder löschen um etwas neues zu schreiben.

  • Ich bin gerade dabei mit mit der _WinAPI Bibliothek ein bisschen vertraut zu machen und versuche hier gerade ganz simpel einen Text auf den Bildschirm zu schreiben. Den Timer hab ich erst eingefügt, aber es bleibt mir immer hier der alte Text erhalten, was dann irgend wann ein rotes Quadrat ergibt  :whistling: . Das möchte ich nicht. Ich möchte das man hier die Zahlen ja lesen kann.

    Da die WinAPI doch recht umfangreich ist, wäre ich hier für jeden Tipp dankbar, wie ich hier ein Update hinbekomme.

    Danke schon im Voraus

    Nun der Code um den es geht:

    Code
    #include <WinAPI.au3>#include <WindowsConstants.au3>#include <FontConstants.au3>
    Global $tRECT, $hFont, $hOldFont, $hDC
    HotKeySet("{ESC}", "_Exit")
    $tRECT = DllStructCreate($tagRect)DllStructSetData($tRECT, "Left", 5)DllStructSetData($tRECT, "Top", 5)DllStructSetData($tRECT, "Right", 250)DllStructSetData($tRECT, "Bottom", 50)
    $hDC = _WinAPI_GetDC(0)$hFont = _WinAPI_CreateFont(50, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, _		$OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')$hOldFont = _WinAPI_SelectObject($hDC, $hFont)
    _WinAPI_SetTextColor($hDC, 0x0000FF)_WinAPI_SetBkColor($hDC, 0x000000); comment next line to get black background instead of transparent one_WinAPI_SetBkMode($hDC, $TRANSPARENT)$timer=TimerInit()While 1	$time=TimerDiff($timer)	_WinAPI_DrawText($hDC, $time, $tRECT, $DT_CENTER)	Sleep(100)WEnd
    Func _Exit()	_WinAPI_SelectObject($hDC, $hOldFont)	_WinAPI_DeleteObject($hFont)	_WinAPI_ReleaseDC(0, $hDC)	_WinAPI_InvalidateRect(0, 0)	$tRECT = 0	ExitEndFunc   ;==>_Exit

    Einmal editiert, zuletzt von BinäryChief (9. September 2013 um 06:06)

  • Bitte verwende in Zukunft Den "Quellcode" Tab im Beitragseditor und klicke vor dem Absenden eines Beitrags nochmal auf "Vorschau", damit solche Formatierungsfehler nicht vorkommen.
    Ich habe mal dein Script für dich auseinandergefriemelt:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <FontConstants.au3>

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

    Global $tRECT, $hFont, $hOldFont, $hDC

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

    HotKeySet("{ESC}", "_Exit")

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

    $tRECT = DllStructCreate($tagRect)
    DllStructSetData($tRECT, "Left", 5)
    DllStructSetData($tRECT, "Top", 5)
    DllStructSetData($tRECT, "Right", 250)
    DllStructSetData($tRECT, "Bottom", 50)

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

    $hDC = _WinAPI_GetDC(0)
    $hFont = _WinAPI_CreateFont(50, 0, 0, 0, 400, False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Arial')
    $hOldFont = _WinAPI_SelectObject($hDC, $hFont)

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

    _WinAPI_SetTextColor($hDC, 0x0000FF)
    _WinAPI_SetBkColor($hDC, 0x000000) ;Comment next line to get black background instead of transparent one
    _WinAPI_SetBkMode($hDC, $TRANSPARENT)

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

    $timer = TimerInit()

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

    While 1
    $time = TimerDiff($timer)
    _WinAPI_DrawText($hDC, $time, $tRECT, $DT_CENTER)
    Sleep(100)
    WEnd

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

    Func _Exit()
    _WinAPI_SelectObject($hDC, $hOldFont)
    _WinAPI_DeleteObject($hFont)
    _WinAPI_ReleaseDC(0, $hDC)
    _WinAPI_InvalidateRect(0, 0)
    $tRECT = 0
    Exit
    EndFunc ;==>_Exit

    [/autoit]


    Das einzige was du in der Hauptschleife machst, ist bei jedem Durchgang einen neuen String zu zeichnen. Wieso erwartest du, dass dadurch der alte verschwindet? :P
    Stell dir den Ablauf deines Programms so vor: Du hast ein Blatt Papier, nimmst einen Bleistift und schreibst "alkdfjslh" darauf. Jetzt schreibst du "askjbasfdö" an die exakt gleich Stelle. Was passiert? Die Texte überlagern sich, weil der Zeichenbereich davor nicht gesäubert/zurückgesetzt wurde.
    Im Programm machst du das, indem du einfach den Zeichenbereich mit der gewünschten Hintergrundfarbe übermalst, bevor du etwas neues zeichnen willst.

    Ich würde dir allerdings empfehlen, nicht direkt auf den Desktop zu zeichnen, da dass ein recht unsauberer Prozess ist. Wenn du ein eigenes Fenster erstellst, das komplett transparent machst und dann darauf mit den GDI32 Funktionen rummalst, kannst du das auch wieder zuverlässig nach jedem Zeichenvorgang zurücksetzen, ohne dass dabei etwas schiefläuft oder alles anfängt zu flackern.

  • Danke schön ... ja ist mein erster Post hier in dem Forum. Danke für den Hinweis.

    Ja das ganze ist für ein anderes Programm gedacht. Möchte mir hier direkt auf dem Bildschirm statische Daten anzeigen lassen, während ich das Fenster halt offen habe. Da es ein von einer kleinen "Hinterhof" Firma programmierte Programm ist, gibt es da auch keine Schnittstellen, wie bei Excel & Co. Daher überlege ich, ob ich das halt an geeigneter Stelle einfach in einem kleinen Fenster (Rechteck) auf den Bildschirm schreibe.

    Mir war allerdings schon klar, dass ich das löschen muss, darum geht es mir ja gerade. Mit welcher Funktion könnte man dies denn?

    Ich habe hier noch ein Bespiel gefunden, in welchem das wohl gemacht wird. Hier wird einfach ein Gitter gezeichnet ... mehr nicht. Aber wohl auch in Transparentem Fenster, wie von name22 schon als Verbesserungsvorschlag genannt. Heute habe ich erst anfangen mich mit der WinApi Bibliothek auseinander zu setzen. Ich habe halt noch keine Ahnung und keinen Überblick über die entsprechenden Funktionen.

    Welche Funktion muss man da Verwenden um das alles zu löschen und auf die richtige Weise neu zu schreiben. Also zum Beispiel das Gitter löschen .. und nach 5 Sekunden wieder das Gitter zeichnen, vielleicht an anderer Stelle.

    Hier nun das andere Beispiel anhand ich versuche ein bisschen Schlauer zu werden.

    Spoiler anzeigen
    [autoit]


    #include <GuiConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>

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

    HotKeySet("{ESC}", "On_Exit")

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

    Global $hGUI, $aRadio[5], $hButton, $iStep

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

    $hGUI = GUICreate("Grid", 150, 190)

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

    GUICtrlCreateLabel("Choose a grid step value", 10, 10, 150, 20)

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

    GUIStartGroup()
    For $i = 0 To 4
    $aRadio[$i] = GUICtrlCreateRadio(100 + ($i * 100), 55, 30 + ($i * 20), 100, 20)
    Next
    GUICtrlSetState($aRadio[0], $GUI_CHECKED)

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

    $hButton = GUICtrlCreateButton("Show Grid", 35, 150, 80, 30)

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

    GUISetState()

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

    While 1

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

    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    Case $hButton
    GUISetState(@SW_HIDE, $hGUI)
    For $i = 0 To 4
    If GUICtrlRead($aRadio[$i]) = 1 Then
    $iStep = GUICtrlRead($aRadio[$i], 1)
    ExitLoop
    EndIf
    Next
    Grid()
    EndSwitch

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

    WEnd

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

    ; -------------

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

    Func Grid()

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

    Local $iVerticals = Floor(@DesktopWidth / $iStep)
    Local $iHorizontals = Floor(@DesktopHeight / $iStep)

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

    Local $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    GUISetBkColor(0x000000)

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

    Local $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)

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

    For $i = 0 To $iVerticals
    $hMask = _WinAPI_CreateRectRgn($i * $iStep, 0, ($i * $iStep) + 1, @DesktopHeight)
    _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
    _WinAPI_DeleteObject($hMask)
    Next

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

    For $i = 0 To $iHorizontals
    $hMask = _WinAPI_CreateRectRgn(0, $i * $iStep, @DesktopWidth, ($i * $iStep) + 1)
    _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
    _WinAPI_DeleteObject($hMask)
    Next

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

    ; Set overall region
    _WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)

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

    GUISetState()

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

    While 1

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

    Sleep(10)

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

    WEnd

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

    EndFunc ;==>Grid

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

    Func On_Exit()

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

    Exit

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

    EndFunc

    [/autoit]

    2 Mal editiert, zuletzt von BinäryChief (7. September 2013 um 19:02)

  • Wie name22 schon sagt, mach es mit GDIp

    "Löschen" kann man das alte gezeichnet übrigens nicht, man muss einfach nochmal ( in deinem Beispiel jedenfalls ) mit schwarz drüber zeichnen.

    Hab noch was gefunden, was ich vor 3-4 Jahren mal gemacht hab, zur Veranschaulichung:

    Spoiler anzeigen
    [autoit]

    ;Author: Greek
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #Include <GDIPlus.au3>

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

    HotKeySet ("{ESC}","_CleanEnd")

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

    Global $GUIBreite=400
    Global $GUIHoehe=150

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

    $hGui=GUICreate("Uhr", $GUIBreite, $GUIHoehe, Default, Default, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOOLWINDOW,$WS_EX_TOPMOST))
    GUISetBkColor(0x000000)
    GUICtrlCreateLabel("", 0, 0, $GUIBreite, $GUIHoehe, -1, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    _WinAPI_SetLayeredWindowAttributes($hGui, 0x000000, 0,0x01)
    _GuiRoundCorners($hGui,0,0,400,150)
    GUISetState()

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

    _GDIPlus_Startup()

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

    $hGraphic=_GDIPlus_GraphicsCreateFromHWND($hGui)
    $hBrush = _GDIPlus_BrushCreateSolid (0xFF00FF00)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ("Arial")
    $hFont = _GDIPlus_FontCreate ($hFamily, 40, 2)
    $tLayout = _GDIPlus_RectFCreate (85, 40, 300, 100)
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, @HOUR&":"&@MIN&":"&@SEC, $hFont, $tLayout, $hFormat, $hBrush)

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

    AdlibRegister("_Update",1000)

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

    While 1
    Sleep ( 200 )
    WEnd

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

    Func _Update()
    _GDIPlus_GraphicsClear($hGraphic,0xFF000000)
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, @HOUR&":"&@MIN&":"&@SEC, $hFont, $tLayout, $hFormat, $hBrush)
    EndFunc

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

    Func _CleanEnd()
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose ($hBrush)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
    Exit
    EndFunc

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

    Func _GuiRoundCorners($hWnd, $x1, $y1, $x3, $y3)
    Local $pos, $ret, $ret2
    $pos = WinGetPos($hWnd)
    $ret = DllCall('gdi32.dll', 'long', 'CreateRoundRectRgn', 'long', $x1, 'long', $y1, 'long', $pos[2], 'long', $pos[3], 'long', $x3, 'long', $y3)
    If $ret[0] Then
    $ret2 = DllCall('user32.dll', 'long', 'SetWindowRgn', 'hwnd', $hWnd, 'long', $ret[0], 'int', 1)
    If $ret2[0] Then
    Return 1
    Else
    Return 0
    EndIf
    Else
    Return 0
    EndIf
    EndFunc

    [/autoit]
    [autoit]

    _GDIPlus_GraphicsClear($hGraphic,0xFF000000)

    [/autoit]

    Der Befehl zeichnet nochmal über alles drüber mit schwarz, dadurch verschwindet die alte Zeit immer.

    [autoit]

    _WinAPI_SetLayeredWindowAttributes($hGui, 0x000000, 0,0x01)

    [/autoit]


    Hier sag ich noch das die Farbe Schwarz transparent sein soll.

    Gruß Greek

  • Danke dir Greek für das Beispiel. Genau sowas habe ich gebraucht.

    Was ich aber noch nicht verstehe, wieso soll ich hier GDIPlus verwenden? .. Was ist da besser?

    Dann habe ich noch eine Frage. Wo bestimmst du in deinem Bespiel mit der Uhr die Position der Uhr auf dem Desktop?

    [autoit]


    $hGui=GUICreate("Uhr", $GUIBreite, $GUIHoehe, Default, Default, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOOLWINDOW,$WS_EX_TOPMOST))
    GUISetBkColor(0x000000)

    [/autoit]

    Sind das hier die Default Einträge?

    Einmal editiert, zuletzt von BinäryChief (7. September 2013 um 19:27)

  • Wenn es dir keine zu grossen Umstände macht .. das wäre wirklich nett. Ich sauge gerade alles zu dem Thema auf wie ein Schwamm ^^

    Mmm vllt sollte ich meine vorherige Frage vllt ein bisschen umformulieren. Was ist denn eigentlich der Vor/Nachteil der Winapi bzw. von GDIPlus? Was kann die eine besser als die andere? Ich hatte mit beiden noch nichts zu tun. Für was sind die beiden Biliotheken schwerpunkttechnisch? ...

  • Dann habe ich noch eine Frage. Wo bestimmst du in deinem Bespiel mit der Uhr die Position der Uhr auf dem Desktop?

    [autoit]


    $hGui=GUICreate("Uhr", $GUIBreite, $GUIHoehe, Default, Default, $WS_POPUP, BitOR($WS_EX_LAYERED,$WS_EX_TOOLWINDOW,$WS_EX_TOPMOST))
    GUISetBkColor(0x000000)

    [/autoit]

    Sind das hier die Default Einträge?

    Steht in der Hilfe bei GUICreate

    Zitat

    left [optional] The left side of the dialog box. By default (-1), the window is centered. If defined, top must also be defined.
    top [optional] The top of the dialog box. Default (-1) is centered

    -1 kann man auch statt Default schreiben.

  • Was mir bis jetzt noch niemand beantwortet hat und worauf ich schon gerne eine Antwort hätte. Worin liegen denn die Vor und Nachteile dieser zwei Bibliotheken? :wacko: Wenn es keine geben sollte, ist das auch ne Antwort. ^^

    Danke aber schon mal für eure Hilfreiche Unterstützung.

  • Hi,

    Zitat

    Was ist denn eigentlich der Vor/Nachteil der Winapi bzw. von GDIPlus? Was kann die eine besser als die andere? Ich hatte mit beiden noch nichts zu tun. Für was sind die beiden Biliotheken schwerpunkttechnisch? ...

    Die WinAPI (Windows Application Programming Interface) fasst sämtliche für Windows relevanten Funktionen zusammen, ist also der Oberbegriff für alle vom Betriebssystem bereitgestellten Funktionen.
    Diese Funktionen unterteilen sich in diverse Gruppen, je nach Anforderung.
    Grafikbe- und Verarbeitung bspw. wird mit den GDI (Graphics Device Interface) - Funktionen vom Betriebssystem zur Verfügung gestellt.

    Um bspw. ein Bild zu drehen, zu verkleinern oder die Farben zu bearbeiten KANN man GDI-Funktionen nutzen. Man kann aber auch je nach Anforderung diese Funktionen durch eigene Ersetzen oder erweitern.

    Beispielscripte für Grafikbe- und Verarbeitung gibt es hier im Forum reichlich, übrigens auch in der Hilfe!