Ich habe das ganze jetzt anders geregelt, so dass ich nur einen StartDrawing-Block benötige.
Es ging hier um eine "Windows XP-sichere" Version einer Screenshotfunktion (mit Ausschnittwahl) von verdeckten Fenstern. Codebeispiel unten.
Dabei ist folgende, weitere Frage aufgekommen: Zeigt der PB-LibraryViewer gar keine Images an, die für eine Imagegadget verwendet werden? Im Beispiel unten ist nach Aufruf von ShowLibraryViewer("Image") zwar kein eigenständiges Image mehr aktiv, aber zumidndest das Image, welches im ImageGadget gesetzt worden ist.
Edit: Aha, offenbar benötigt das ImageGadget eh immer ein separates Image. Demzufolge darf ich das FreeImage() auch erst bei Programmende ausführen. Ich hatte mich nämlich gewundert, dass das Imagegadget zwar einmalig den Screenshot anzeigt, aber das Bild nicht redrawed, wenn man andere Fenstern drüber zieht. Verschiebt man FreeImage(iImage) an das Ende des Programms, dann läuft es wie erwartet.
Edit 2: Aha2, wenn ich ein CanvasGadget nehme und dem das Image via "
SetGadgetAttribute(MyCanvasGadget, #PB_Canvas_Image, ImageID(iImage))" zuweise, dann kann ich es auch sofort nach der Zuweisung wieder löschen. Offenbar legt das CanvasGadget eine interne Kopie davon an.
Code: Alles auswählen
EnableExplicit
#ImageGadget = 0
Prototype.i PrintWindow(iHandle.i, iDC.i, iFlags.i)
Global.i PrintWindow_.PrintWindow, iImage, iCalc
Procedure.i CreateImageFromScreenshot(sWindowTitel.s, x.i, y.i, iWidth, iHeight.i)
; +-----------------------------------------------------------------
; |Description : Grabbt den Inhalt eines Fensters oder einen Ausschnitt davon und erzeugt daraus ein neues Image
; |Arguments : sWindowTitel: Kompletter Titel des Fensters das abfotografiert werden soll
; | : x : X-Position des auszuschneidenden Screenshot-Bereichs
; | : y : Y-Position des auszuschneidenden Screenshot-Bereichs
; | : iWidth : Breite des auszuschneidenden Screenshot-Bereichs
; | : iHeight : Höhe des auszuschneidenden Screenshot-Bereichs
; |Results : Image-Nummer des neuen Images oder 0, wenn eine Fehler aufgetreten ist
; |Remarks : -
; +-----------------------------------------------------------------
Protected.i iImage1, iImage2, iWindowHandle, iImageDC
Protected.RECT stWindowRect
If iWidth < 1 Or iHeight < 1
; Die Screenshot-Ausmaße sind ungültig
Goto ErrorExit
EndIf
If OpenLibrary(0, "user32.dll") = 0
; Library konnte nicht geöffnet werden
Goto ErrorExit
EndIf
; Das Fenster anhand des kompletten Titels finden
PrintWindow_ = GetFunction(0, "PrintWindow")
iWindowHandle = FindWindow_(0, sWindowTitel)
If iWindowHandle = 0
; Das Fenster wurde nicht gefunden
Goto ErrorExitCloseLib
EndIf
; Ermitteln der Ausmaße des zu grabbenden Fensters
GetWindowRect_(iWindowHandle, @stWindowRect)
If stWindowRect\right < 1 Or stWindowRect\bottom < 1
; Die Ausmaße des zu grabbenden Fensters sind nicht gültig
Goto ErrorExitCloseLib
EndIf
; Erstellen eines temporären Images in der Größe des Screenshots
iImage1 =CreateImage(#PB_Any, stWindowRect\right, stWindowRect\bottom)
If iImage1 < 0
; Das Image konnte nicht erstellt werden
Goto ErrorExitCloseLib
EndIf
; Kopieren des Screenshots in ein temporäres Image
iImageDC = StartDrawing(ImageOutput(iImage1))
If iImageDC = 0
; Device Context ist nicht für Zeichenoperationen gültig
Goto ErrorExitCloseLib
EndIf
Printwindow_(iWindowHandle, iImageDC, 0)
StopDrawing()
iImage2 = GrabImage(iImage1, #PB_Any, x, y, iWidth, iHeight)
If iImage2 = 0
; Device Context ist nicht für Zeichenoperationen gültig
Goto ErrorExitFreeImage:
EndIf
FreeImage(iImage1)
CloseLibrary(0)
ProcedureReturn iImage2
ErrorExitFreeImage:
FreeImage(iImage1)
ErrorExitCloseLib:
CloseLibrary(0)
ErrorExit:
ProcedureReturn 0
EndProcedure
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 120, 120, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ImageGadget(#ImageGadget, 10, 10, 100, 100, 0, #PB_Image_Border)
iCalc = RunProgram("calc.exe","","",#PB_Program_Open)
Delay(1000)
iImage = CreateImageFromScreenshot("Rechner", 0, 0, 100, 100)
SetGadgetState(#ImageGadget, ImageID(iImage))
Debug iImage
FreeImage(iImage)
ShowLibraryViewer("Image")
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
KillProgram(iCalc)
CloseProgram(iCalc)
EndIf