GDI+ negative Koordinaten

  • Hallo an alle,

    Ich verwende den GDI+ mit dem 0er DC ( direkt auf Bildschirm ).

    Problem: wenn es an negative Koordinaten geht wird nichts mehr angezeigt. Auch nicht mit Transformation:
    (Das gilt, wenn 2. Monitor links vom Hauptmonitor steht)

    kennt sich da jemand aus?

    tausend Dank

    Blues

  • #include <WindowsConstants.au3>

    Code
    $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop)
    DllCall('gdi32.dll', 'int', 'Rectangle', 'hwnd', $hDC, 'int', -500 , 'int', 0 , 'int', 500, 'int', 500 )
    _WinAPI_ReleaseDC( 0, $hDC)
  • [autoit]

    _GDIPlus_GraphicsCreateFromHWND( 0 )

    [/autoit]

    Ist das nur Ersatz odert dein eigtl. Code?

  • Ich möchte wirklich direkt auf den Bildschirm zeichnen. Ich weis eigene Fenster sind in vielerlei Hinsicht günstiger.
    Aber es geht wirklich nur so. Hast du eine Idee? (vor allem warum es per Dll geht aber per GDI+-Wrapper nicht)

    Gruß

    Blues

  • Hi,

    du kannst auch einfach auf ein transparentes Fenster zeichnen.

    Beispiel:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GDIPlus.au3>
    #include <timers.au3>
    #include <Misc.au3>

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

    $dll = DllOpen("user32.dll")

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

    Global $ballpos1=@DesktopWidth/2
    Global $ballpos2=@DesktopHeight/2
    Global $BewegungSenkrecht=Random(5, 7, 1)
    Global $BewegungWagrecht=Random(5, 7, 1)
    Global $Speed=10

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

    _GDIPlus_Startup()

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

    Global $hGui = GUICreate("Rahmen", @DesktopWidth, @DesktopHeight, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
    GUISetBkColor(0xABCDEF)
    _WinAPI_SetLayeredWindowAttributes($hGui, 0xABCDEF, 255)
    GUISetState()
    Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $Pinsel = _GDIPlus_PenCreate(0xFF0000FF, 20)
    Global $vanish = _GDIPlus_PenCreate(0xFF000000, 20)
    $t1 = _Timer_SetTimer(0, 10, "move")
    $begin=TimerInit()

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

    AdlibRegister ( "_check", 50 )

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

    While 1
    $nmsg=GUIGetMsg()
    Switch $nmsg
    Case $gui_event_close
    Exit
    EndSwitch
    WEnd

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

    Func _ende()
    _GDIPlus_GraphicsClear ( $hGraphic, 0xFFABCDEF )
    _GDIPlus_PenDispose($Pinsel)
    _GDIPlus_PenDispose($vanish)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_ende

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

    Func move($a, $b, $c, $d)
    _GDIPlus_GraphicsDrawLine ( $hGraphic, $ballpos1, $ballpos2, $ballpos1+50, $ballpos2+50, $vanish )
    $ballpos1+=$BewegungWagrecht * $Speed
    $ballpos2+=$BewegungSenkrecht * $Speed
    _GDIPlus_GraphicsDrawLine ( $hGraphic, $ballpos1, $ballpos2, $ballpos1+50, $ballpos2+50, $Pinsel )
    If $ballpos1 >= @DesktopWidth - 80 And $BewegungWagrecht > 0 Then $BewegungWagrecht = Random(-7, -5, 1)
    If $ballpos1 < 10 And $BewegungWagrecht < 0 Then $BewegungWagrecht = Random(5, 7, 1)
    If $ballpos2 >= @DesktopHeight - 95 And $BewegungSenkrecht > 0 Then $BewegungSenkrecht = Random(-7, -5, 1)
    If $ballpos2 < 30 And $BewegungSenkrecht < 0 Then $BewegungSenkrecht = Random(5, 7, 1)
    If _GDIPlus_PenGetColor ( $vanish )=0xFF000000 Then
    _GDIPlus_PenSetColor ( $vanish, 0xFFFFFF00 )
    ElseIf _GDIPlus_PenGetColor ( $vanish )=0xFFFFFF00 Then
    _GDIPlus_PenSetColor ( $vanish, 0xFFFF0000 )
    ElseIf _GDIPlus_PenGetColor ( $vanish )=0xFFFF0000 Then
    _GDIPlus_PenSetColor ( $vanish, 0xFF00FF00 )
    ElseIf _GDIPlus_PenGetColor ( $vanish )=0xFF00FF00 Then
    _GDIPlus_PenSetColor ( $vanish, 0xFF000000 )
    EndIf
    ;~ $dif=TimerDiff( $begin )
    ;~ If $dif>12000 Then
    ;~ _GDIPlus_GraphicsClear ( $hGraphic, 0xFFABCDEF )
    ;~ $begin=TimerInit()
    ;~ EndIf
    EndFunc ;==>move

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

    Func _check()
    If _IsPressed ( "1B", $dll ) Then
    _ende()
    EndIf
    EndFunc

    [/autoit]

    Gruß Greek

    Edit:

    Ah hab was vergessen, man kann nicht mehr hindurch drücken, dafür gibts aber eine Lösung - moment.

    Edit2:

    Spoiler anzeigen
    [autoit]

    ;### UDF Start
    #Include <WinAPI.au3>
    #include <WindowsConstants.au3>

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

    Global Const $GWL_EXSTYLE = -20

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

    ;===============================================================================
    ;
    ; Function Name: _Win_SetClickThrough($hWnd,$noclic = True)
    ; Description:: Makes a window to not receive mouse input
    ; Parameter(s): $title -> Title or hWnd of Window
    ; $text [Optional] -> Text in Window
    ; $noclic [Optional] -> If False, the window regains MouseInput otherwise it will loose it, defalut: True
    ; Requirement(s): <WINApi.au3>
    ; Return Value(s): Success: 1, Error0 and @error
    ; @error Values: 1 -> Window does not exist
    ; 2 -> Error in Setting the Styles
    ; Author(s): Prog@ndy
    ;
    ;===============================================================================
    ;
    Func _Win_SetClickThrough($title,$text = "",$noclic = True)
    Local $hWnd = WinGetHandle($title,$text)
    If @error Then Return SetError(1,0,0)
    If $noclic Then
    _WinAPI_SetWindowLong($hWnd,$GWL_EXSTYLE,BitOR(_WinAPI_GetWindowLong($hWnd,$GWL_EXSTYLE),$WS_EX_TRANSPARENT))
    If @error Then Return SetError(2,0,0)
    WinSetTrans($hWnd,"",255) ; Sets the Layered Attribute, but still shows the window :)
    If @error Then Return SetError(2,0,0)
    Else
    _WinAPI_SetWindowLong($hWnd,$GWL_EXSTYLE,BitAND(_WinAPI_GetWindowLong($hWnd,$GWL_EXSTYLE),BitNOT($WS_EX_TRANSPARENT)))
    If @error Then Return SetError(2,0,0)
    EndIf
    Return 1
    EndFunc
    ;### UDF END

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

    ;Example:
    $win = WinGetHandle("Unbenannt")

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

    If @error = 1 Then
    Run("notepad.exe")
    WinWait("Unbenannt")
    $win = WinGetHandle("Unbenannt")
    EndIf

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

    WinActivate($win)
    _Win_SetClickThrough($win)
    MsgBox(0, '', "Notepad receives no Mouse Clicks anymore, Click OK to Restore")
    _Win_SetClickThrough($win,"",0)

    [/autoit]
  • Hallo Geek,

    Das ist wirklich nett, vielen Dank für die Mühe.

    Aber ich würde wirklich gern auf ein solches Fenster verzichten (komplexitätsgründe)


    Ich würde gern wissen warum man per dll auch negative koordinaten angeben kann,
    der GDI+ (der die Dlls ja quasi verwrapt) das aber nicht kann.


    Gruß

    Blues

  • Dann musst du aber das Handle vom Desktop verwenden.
    _GDIPlus_GraphicsCreateFromHWND( 0 ) wird nicht funktionieren.

    Lösung:

    [autoit]

    _GDIPlus_GraphicsCreateFromHWND( _WinAPI_GetDesktopWindow() )

    [/autoit]


    oder

    [autoit]


    _GDIPlus_GraphicsCreateFromHDC( _WinAPI_GetDC(0) ) ;GetDC(0) gibt dir den DeviceContext des Desktops zurück.

    [/autoit]


    EDIT:
    Machs lieber so, da sonst ein Speicherleck entsteht (falls du die DC-Variante benutzt):

    Spoiler anzeigen
    [autoit]

    Local $hdcDesktop = _WinAPI_GetDC(0)_GDIPlus_GraphicsCreateFromHDC( $hdcDesktop )_WinAPI_ReleaseDC( $hdcDesktop )$hdcDesktop = 0

    [/autoit]


    Keine Ahnung warum mein Browser gerade herumspinnt. Auf jeden Fall solltest du zwischen den Befehlen einen Zeilenumbruch machen.

    2 Mal editiert, zuletzt von CentuCore (5. August 2013 um 20:44)