Page 1 of 1
Capturing windows (inactiv, too)
Posted: Mon Dec 24, 2007 6:45 am
by Hroudtwolf
Hi,
This code demonstrates how to capture windows, and also inactive windows on windowsXP.
Best regards
Wolf
Code: Select all
; PureBasic-Lounge.de
; Author: Hroudtwolf
; Date: 04. November 2007
; OS: Windows
; Demo: No
Prototype.l pPrintWindow(hWnd.l, hDc.l, lFlags.l)
Define .l hLib = OpenLibrary(#PB_Any , "user32.dll")
Define .pPrintWindow PrintWindow_ = GetFunction(hLib , "PrintWindow")
Procedure CreateWndSnapshot (hWnd.l)
Protected hdc .l = GetWindowDC_(hWnd)
Protected RC .RECT
Protected hBitmap .l
Shared PrintWindow_
If Not hdc
ProcedureReturn #Null
EndIf
hdcMem = CreateCompatibleDC_(hdc)
If Not hdcMem
ProcedureReturn #Null
EndIf
GetWindowRect_(hWnd, RC)
hBitmap = CreateCompatibleBitmap_(hdc, RC\right , RC\bottom)
If Not hBitmap
ProcedureReturn #Null
EndIf
SelectObject_(hdcMem, hBitmap)
PrintWindow_(hwnd, hdcMem, 0)
DeleteObject_(hdcMem)
ProcedureReturn hBitmap
EndProcedure
If OpenWindow(0, 0, 0, 1024 , 30, "Window in a box", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ImageGadget(0, 0, 0, 1024 , 30, CreateWndSnapshot (FindWindow_("Shell_TrayWnd", #Null)))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Posted: Mon Dec 24, 2007 8:11 am
by electrochrisso
Could come in handy! Thanks.

Posted: Mon Dec 24, 2007 12:19 pm
by ABBKlaus
nice, but eats GDI-Objects

Posted: Mon Dec 24, 2007 12:46 pm
by gnozal
Shouldn't it be
instead of
?
Posted: Mon Dec 24, 2007 2:28 pm
by netmaestro
Yes, DeleteDC for hdcmem, and you miss:
which is the other leak. Also, when a programmer calls this procedure, he's got to remember to do a DeleteObject_() on every bitmap returned as soon as he's finished with it, or it's a huge leak.
Posted: Mon Dec 24, 2007 3:21 pm
by Hroudtwolf
Yes. Your'e right.
Best regards and merry christmas!
Wolf
Posted: Mon Dec 24, 2007 3:26 pm
by Dare
Thanks for the pointers, tricks and tips here. (Love the way things develop on these boards).
Great new year to all!
Posted: Wed Dec 26, 2007 3:53 am
by yrreti
I have a question:
I ran your code once and it 'worked ok'. Then I ran the same code later and it
always errors out on the
line. I tried repasting your code again and it still errors on that line.
The error is :
Line 33:PrintWindow_() is not a function, array, macro or linked list.
The fact that it ran ok the first time bugs me? Any ideas?
Thanks for your time.
Posted: Wed Dec 26, 2007 3:58 am
by netmaestro
The PrintWindow api is not available directly in PureBasic, like so many other api commands are. You must call the function from the dll, e.g. using a prototype as htroudwolf has done, or CallFunction, etc. etc. Because unfortunately PrintWindow_() really isn't a function, array, macro or linked list.
Posted: Wed Dec 26, 2007 10:02 pm
by Psychophanta
netmaestro wrote:The PrintWindow api is not available directly in PureBasic, like so many other api commands are. You must call the function from the dll, e.g. using a prototype as htroudwolf has done, or CallFunction, etc. etc. Because unfortunately PrintWindow_() really isn't a function, array, macro or linked list.
Here it works without any problem

Posted: Wed Dec 26, 2007 10:09 pm
by netmaestro
Code: Select all
Prototype.l pPrintWindow(hWnd.l, hDc.l, lFlags.l)
Define .l hLib = OpenLibrary(#PB_Any , "user32.dll")
Define .pPrintWindow PrintWindow_ = GetFunction(hLib , "PrintWindow")
As long as this section is intact, it should work everywhere*. Without it, the command won't be recognized.
*
Included in Windows XP and Windows Server 2003. Windows 95/98/Me: Unsupported.
Posted: Wed Dec 26, 2007 10:40 pm
by Psychophanta

Sorry, i didn't watch that section. :roll:
Posted: Wed Dec 26, 2007 11:56 pm
by yrreti
Thanks netmaestro for your reply and also the good explanation. The code you displayed is exactly what is
listed. The puzzling thing is that it worked the first time I ran it. I just can't understand why it doesn't work now.
I was beginning to suspect my user32.dll got messed up and so I looked into it and found the PrintWindow intact.
I even tried a different user32.dll and it still fails? I'm using XP Pro. Anyway thanks for your input.
Posted: Fri Dec 28, 2007 11:51 am
by ABBKlaus
here is my version : (without GDI-leaks)
Code: Select all
; PureBasic-Lounge.de
; Author: Hroudtwolf
; Date: 04. November 2007
; OS: Windows
; Demo: No
Prototype.l pPrintWindow(hWnd.l, hDc.l, lFlags.l)
Global hLib.l = OpenLibrary(#PB_Any , "user32.dll")
Global PrintWindow_.pPrintWindow = GetFunction(hLib , "PrintWindow")
Procedure CreateWndSnapshot (hWnd.l,Image.l=#PB_Any)
Protected hdc .l = GetWindowDC_(hWnd)
Protected RC .RECT
Protected res .l
Protected Img .l
Protected DC .l
If Not hdc
ProcedureReturn #Null
EndIf
If GetWindowRect_(hWnd, RC)
Res=CreateImage(Image,RC\right-RC\left,RC\bottom-RC\top,#PB_Image_DisplayFormat)
If Image=#PB_Any
Img=Res
Else
Img=Image
EndIf
If Res
DC=StartDrawing(ImageOutput(Img))
PrintWindow_(hwnd, DC, 0)
StopDrawing()
EndIf
EndIf
If hdc
ReleaseDC_(hWnd,hdc)
EndIf
If Image=#PB_Any
ProcedureReturn Img
Else
ProcedureReturn Res
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 1024 , 30, "Window in a box", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ImageGadget(0, 0, 0, 1024 , 30, 0)
If CreateWndSnapshot(FindWindow_("Shell_TrayWnd", #Null),0)
SetGadgetState(0,ImageID(0))
EndIf
Repeat
Event=WaitWindowEvent(100)
If Event=0
If CreateWndSnapshot(FindWindow_("Shell_TrayWnd", #Null),0)
SetGadgetState(0,ImageID(0))
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
Posted: Sat Dec 29, 2007 4:39 am
by yrreti
Thank you ABBKlaus for the code.
Yours works on my system.