Crosshair Overlay

05/19/2012 13:42 subzeroowner#1
Hallo Community

In letzter Zeit spiele ich MW3 und wollte mir dafür ein kleines Script schreiben, welches einen perfekten Quickscope macht. An sich funktioniert alles, jedoch habe ich bemerkt, dass es ein Wenig schwer ist ohne Crosshair. Hier im Forum habe ich [Only registered and activated users can see links. Click Here To Register...] gefunden und habe dort den Code verwendet, um ein kleines Kreuz nach klicken einer Taste über allem auf dem Bildschirm anzuzeigen.

Das ganze funktioniert gut, nun habe ich auch noch eingebaut, dass er immer die negative Farbe von einem Pixel neben dem Crosshair nimmt. Dies funktioniert ebenfalls, jedoch wird durch das aktualisieren mein RAM bis auf 4 GB vollgemüllt mit Farbwerten, welche ich am liebsten löschen will. Jedoch kriege ich das nicht hin.

Nun zum Code:
Meine Funktion, welches das GUI erstellt (kopiert vom genannten Thread):
PHP Code:
Func _Crosshair()
    If 
$Crosshair True Then
        $hDummy 
GUICreate("")
        
$hGUI GUICreate("", @DesktopWidth, @DesktopHeight00$WS_POPUPBitOR($WS_EX_LAYERED$WS_EX_TOPMOST,$WS_EX_TRANSPARENT),$hDummy)
        
GUISetBkColor(0xABCDEF$hGUI)
        
_WinAPI_SetLayeredWindowAttributes($hGUI0xABCDEF255)
        
GUISetState()
    Else
        
_GDIPlus_GraphicsDispose($hGraphics)
        
_GDIPlus_BitmapDispose($hBitmap)
        
_GDIPlus_PenDispose($hPen)
        
GUIDelete($hGUI)
    EndIf
EndFunc 
Meine Endlosschleife, welche die Keys sucht und wenn das Crosshair an ist die Farbe aktualisiert:
PHP Code:
While 1
    
If _IsPressed($keyPause$dllThen
        _TogglePause
()
    EndIf
    If 
_IsPressed($keyExit$dllThen
        _Terminate
()
    EndIf
    If 
_IsPressed($qsHotkey$dllThen
        _Quickscope
()
    EndIf
    If 
_IsPressed($chHotkey$dllThen
        $Crosshair 
Not $Crosshair
        Sleep
(200)
        
_Crosshair()
    EndIf
    If 
$Crosshair True Then
        _GDIPlus_GraphicsDispose
($hGraphics)
        
_GDIPlus_BitmapDispose($hBitmap)
        
_GDIPlus_PenDispose($hPen)
        
$hGraphics _GDIPlus_GraphicsCreateFromHWND($hGUI)
        
$hBitmap _GDIPlus_BitmapCreateFromGraphics(@DesktopWidth, @DesktopHeight$hGraphics)
        
$hBackBuffer _GDIPlus_ImageGetGraphicsContext($hBitmap)
        
$hPen _GDIPlus_PenCreate("0x" Hex(_InvertColor(PixelGetColor(@DesktopWidth/2, @DesktopHeight/2)), 8),2)
        
_GDIPlus_GraphicsDrawLine($hGraphics$wedith-10$height$wedith+10$height$hPen)
        
_GDIPlus_GraphicsDrawLine($hGraphics$wedith$height-10$wedith$height+10$hPen)
        
_GDIPlus_GraphicsDrawImage($hGraphics$hBitmap$wedith$height)
    EndIf
WEnd 
Ich weiss jetzt nicht, ob das mit dem _GDIPlus_PenDispose() usw. das Richtige ist, denn weder mit noch ohne dem schreibt er den RAM voll.

Ich hoffe ihr wisst wie ich das machen kann.

Freundliche Grüsse
subzeroowner
05/19/2012 14:36 Lawliet#2
Statt jedesmal die GUI neu zu erstellen, solltest du mit @SW_SHOW und @SW_HIDE arbeiten.
So sparst du dir schonmal diesen Code:
Code:
$hDummy = GUICreate("") 
        $hGUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST,$WS_EX_TRANSPARENT),$hDummy) 
        GUISetBkColor(0xABCDEF, $hGUI) 
        _WinAPI_SetLayeredWindowAttributes($hGUI, 0xABCDEF, 255) 




 _GDIPlus_GraphicsDispose($hGraphics) 
        _GDIPlus_BitmapDispose($hBitmap) 
        _GDIPlus_PenDispose($hPen) 
        GUIDelete($hGUI)
Ansonsten bau doch einfach mal in deine Schleifen ein Sleep(10-100) ein.
05/19/2012 14:54 holbirne#3
geht das für jedes spiel?:D

EDIT: ah ja und ein screen wäre net :D
05/19/2012 15:55 Lawliet#4
Das ist kein Release!
05/19/2012 16:43 subzeroowner#5
Ich habe nun wie du gesagt hast den Code ein Bisschen gekürtzt und das Neuerstellen rausgenommen und nun sieht das mit dem RAM schon viel besser aus.

Hier der Code:
PHP Code:
Func _Crosshair()
    
$Crosshair Not $Crosshair
    Sleep
(200)
    If 
$Crosshair True Then
        $hGUI 
GUICreate("", @DesktopWidth, @DesktopHeight00$WS_POPUPBitOR($WS_EX_LAYERED$WS_EX_TOPMOST,$WS_EX_TRANSPARENT))
        
GUISetBkColor(0xABCDEF$hGUI)
        
_WinAPI_SetLayeredWindowAttributes($hGUI0xABCDEF255)
        
$hGraphics _GDIPlus_GraphicsCreateFromHWND($hGUI)
        
$hBitmap _GDIPlus_BitmapCreateFromGraphics(@DesktopWidth, @DesktopHeight$hGraphics)
        
$hBackBuffer _GDIPlus_ImageGetGraphicsContext($hBitmap)
        
GUISetState()
    Else
        
_GDIPlus_GraphicsDispose($hGraphics)
        
_GDIPlus_BitmapDispose($hBitmap)
        
_GDIPlus_PenDispose($hPen)
        
GUIDelete($hGUI)
    EndIf
EndFunc 
PHP Code:
While 1
    Sleep
(50)
    If 
$Crosshair True Then
        $hPen 
_GDIPlus_PenCreate("0x" Hex(_InvertColor(PixelGetColor(@DesktopWidth/2, @DesktopHeight/2)), 8),2)
        
_GDIPlus_GraphicsDrawLine($hGraphics$wedith-10$height$wedith+10$height$hPen)
        
_GDIPlus_GraphicsDrawLine($hGraphics$wedith$height-10$wedith$height+10$hPen)
        
_GDIPlus_GraphicsDrawImage($hGraphics$hBitmap$wedith$height)
    EndIf
WEnd 
Nun habe ich aber noch das Problem, dass das Script wahrscheinlich trotzdem mit dem Pen immer drübermalt und nicht das vorherige Fadenkreuz löscht. Das wirkt sich im 2 Stelligen kByte Bereich aus aber auch so wird der RAM irgendwann einmal voll sein. Wie kann ich das mit _GDIPlus_GraphicsDrawLine und _GDIPlus_GraphicsDrawImage gezeichnete komplett entfernen?
05/19/2012 18:57 Lawliet#6
_GDIPlus_PenDispose
Habe noch nicht viel mit GDI+ gemacht, aber du kannst ja mal versuchen in Zeitabständen über ProcessGetStats den RAM zu prüfen und entsprechend GDI+ zu beenden und wieder zu starten.
Statt Sleep() kannst du auch deine Crosshair Funktion mit einem TimeStamp callen
Code:
_Crosshair(TimerInit())

Func _Crosshair($timestamp)
If $Crosshair and TimerDiff($timestamp) > 200 then
....
endif
EndFunc
So werden andere Funktionen, die evl. noch ausgeführt werden nicht blockiert.