Einen Rahmen außerhalb der GUI ziehen

  • Hallo Community,

    ich suche nach einer Möglichkeit außerhalb einer per AutoIt erstellen GUI einen Rahmen zu ziehen, der aber mit dem Programm zusammen hängt.

    Quasi will ich beim erstem Mausklick, egal wo auf dem Bildschirm, den ersten Punkt des Rechtecks setzten und dann mit einen 2. Mausklick den 2. diagonal gegenüberliegenden Punkt.
    Der Rand dieses Rechecks sollte dann sichtbar sein, solange bis man auf einen weiteren Button in der GUI klickt oder das Programm geschlossen wird.

    Per GDI+ wird das ja nix, weil es ja "auf" einer GUI gezeichnet wird. (korregiert mich wenn ich falsch liege :) )

    Gibt es dazu schon irgendwo einen Thread oder hat jemand schonmal was ähnliches für ein eigenes Programm verwendet?
    Bin über jede Information und Hilfe dankbar :)

    Gruß
    Prixma

  • Hallo, also ich denke es ist auch mit GDI+ Möglich und war indem du 2 Fenster erzeugst 1 Fenster mit der Größe deiner Desktopauflösung und eins (das Sichtbare) mit deinen Buttons usw.., im ersten Fenster was über deine gesamte oberfläche geht kannst du dann deine Punkte makieren und dann von GDI+ zeichnen lassen, ich denke mal das sollte möglich sein

    Gruß Marvin

  • Sowas (ähnliches) gibt es bereits. (wer das erfunden hat weiß ich nicht mehr.....)

    Spoiler anzeigen
    [autoit]

    #include <Misc.au3>
    #include <ScreenCapture.au3>
    #include <WindowsConstants.au3>

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

    While 1
    If _IsPressed(01) Then
    $aMousePosDesk = MouseGetPos()
    $hGui = GUICreate("Screen", 0, 0, $aMousePosDesk[0], $aMousePosDesk[1], $WS_POPUP, $WS_EX_TOOLWINDOW+$WS_EX_TOPMOST)
    GUISetBkColor(0x0090ff)
    WinSetTrans("Screen", "", 100)
    GUISetState()
    Do
    $aNewMousePosDesk = MouseGetPos()
    WinMove("Screen", "", $aMousePosDesk[0], $aMousePosDesk[1], $aNewMousePosDesk[0] - $aMousePosDesk[0], $aNewMousePosDesk[1] - $aMousePosDesk[1])
    Until Not _IsPressed(01)
    $WinPosANDScreenKoords = WinGetPos("Screen", "")
    GUIDelete($hGui)
    For $i = 1 To 9999
    If Not FileExists(@DesktopDir & "\DeskScreenPic" & $i & ".jpg") Then
    Sleep(100)
    _ScreenCapture_Capture(@DesktopDir & "\DeskScreenPic" & $i & ".jpg", $WinPosANDScreenKoords[0], $WinPosANDScreenKoords[1], $WinPosANDScreenKoords[0] + $WinPosANDScreenKoords[2], $WinPosANDScreenKoords[1] + $WinPosANDScreenKoords[3])
    ExitLoop
    EndIf
    Next
    EndIf
    WEnd

    [/autoit]

    Nach dem Start kannst du mit der Maus klicken und ein Viereck ziehen.
    Beim loslassen wird von diesem Feld ein Screenshot gemacht.

    lg
    M

  • So ... mittlerweile hab ich etwas herumprobiert und hab mich jetzt erstmal mit Marsi seiner Variante beschäftigt.

    Das Ergebniss:

    Spoiler anzeigen
    [autoit]

    #include <Misc.au3>
    #include <WindowsConstants.au3>
    $hGui = GUICreate("Field")
    While 1
    If _IsPressed(01) Then
    GUIDelete($hGui)
    $aMousePosDesk = MouseGetPos()
    $hGui = GUICreate("Screen", 0, 0, $aMousePosDesk[0], $aMousePosDesk[1], $WS_POPUP, $WS_EX_TOOLWINDOW+$WS_EX_TOPMOST)
    GUISetBkColor(0x700ff00)
    WinSetTrans("Screen", "", 120)
    GUISetState()
    Do
    sleep(10)
    Until Not _IsPressed(01)
    Do
    $aNewMousePosDesk = MouseGetPos()
    WinMove("Screen", "", $aMousePosDesk[0], $aMousePosDesk[1], $aNewMousePosDesk[0] - $aMousePosDesk[0], $aNewMousePosDesk[1] - $aMousePosDesk[1])
    Until _IsPressed(01)
    Do
    Sleep(10)
    Until not _IsPressed(01)
    EndIf

    WEnd

    [/autoit]

    Falls noch Verbesserungen vorgenommen werden können, dann immer raus damit.

    Deine Variante BugFix ist mir noch nicht ganz klar, aber ich werd nochmal weiter versuchen. :) Hab für das _WinAPI_DrawEdge (so heißt das wohl) zwar im englischen Forum noch etwas gefunden, aber die Anwendung selber ist mir noch nicht so klar, da auch in der AutoIt Hilfe keine Beispiel vorhanden ist.
    Wenn jemand so lieb wäre könnte er ja evtl ein kleines Beispiel zur Verfügung stellen.

    Ansonsten danke erstmal dafür :)
    Hat mir sehr geholfen.

  • Unglaublich das mein Script hier noch rumgeistert, ich dachte das hat sich niemand angeschaut :O

    Zu BugFix Lösung kann ich nur sagen das du das DC des Desktops bekommen musst und auf den kannst du dann zeichnen.
    Ich hätte noch eine Idee, die wäre jedoch etwas kompliziert und umständlich. Es gibt eine UDF mit der man Controls auf (fast) alle GUIs erstellen kann (Natürlich mit ChildGUI die dem Fenster folgt). Du könntest dir die evtl mal anschauen (Hieß AnyGui.au3 oder so) und evtl etwas umschreiben. Dann kannst du das erstellte Child-Fenster transparent machen und das DC nehmen und mit GDI+ draufmalen. Umständlich aber möglich (Hoff/denk ich mal)

    Würde mich interessieren ob das gehen würde.

    Zu dem DC Voschlag von BF:

    [autoit]

    $hDC = _WinAPI_GetWindowDC(0)

    [/autoit]

    Damit bekommst du den Gerätekontext vom Screen auf den du dann zeichnen kannst.

    Beispiel aus der Hilfe:

    [autoit]

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

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

    ShowCross(@DesktopWidth / 2, @DesktopHeight / 2, 20, 2, 0xFF, 3000)

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

    Func ShowCross($start_x, $start_y, $length, $width, $color, $time)
    Local $hDC, $hPen, $obj_orig

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

    $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop)
    $hPen = _WinAPI_CreatePen($PS_SOLID, $width, $color)
    $obj_orig = _WinAPI_SelectObject($hDC, $hPen)

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

    _WinAPI_DrawLine($hDC, $start_x - $length, $start_y, $start_x - 5, $start_y) ; horizontal left
    _WinAPI_DrawLine($hDC, $start_x + $length, $start_y, $start_x + 5, $start_y) ; horizontal right
    _WinAPI_DrawLine($hDC, $start_x, $start_y - $length, $start_x, $start_y - 5) ; vertical up
    ; _WinAPI_DrawLine($hDC, $start_x, $start_y + $length, $start_x, $start_y + 5) ; vertical down
    _WinAPI_MoveTo($hDC, $start_x, $start_y + $length)
    _WinAPI_LineTo($hDC, $start_x, $start_y + 5)

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

    Sleep($time) ; show cross over screen for defined seconds

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

    ; refresh desktop (clear cross)
    _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN)

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

    ; clear resources
    _WinAPI_SelectObject($hDC, $obj_orig)
    _WinAPI_DeleteObject($hPen)
    _WinAPI_ReleaseDC(0, $hDC)
    EndFunc ;==>ShowCross

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