Screenshot of desktop but not current window
Re: Screenshot of desktop but not current window
Just enumerate the windows and use printwindow
if you can get the zorder you could composite them back into an image
or just grab the window your interested in
if you can get the zorder you could composite them back into an image
or just grab the window your interested in
Windows 11, Manjaro, Raspberry Pi OS


- electrochrisso
- Addict

- Posts: 989
- Joined: Mon May 14, 2007 2:13 am
- Location: Darling River
Re: Screenshot of desktop but not current window
Another way might be to make the calculator window fully transparent for the screenshot, someone with good API knowledge may be able to help on this one.
PureBasic! Purely the best 
- electrochrisso
- Addict

- Posts: 989
- Joined: Mon May 14, 2007 2:13 am
- Location: Darling River
Re: Screenshot of desktop but not current window
Here is another idea, move the calculator just out of view of the desktop, take the screenshot, then move it back to its original position, there are so many ways to approach things in programming.
Code: Select all
UsePNGImageEncoder()
Procedure GetDesktopWindows()
h = GetWindow_(GetDesktopWindow_(), #GW_CHILD)
Repeat
If IsWindowVisible_(h) = #True
c$ = Space(999) : GetWindowText_(h, c$, 999)
If c$ <> ""
If c$ = "Calculator"
ExamineDesktops()
Protected WR.RECT
GetWindowRect_(h, WR)
sx = WR\Left
wd = WR\Right - WR\Left
ht = WR\Bottom - WR\Top
MoveWindow_(h,DesktopWidth(0),WR\Top,wd,ht,#True)
Delay (500)
img = CreateImage(#PB_Any, DesktopWidth(0), DesktopHeight(0))
dc = GetDC_(0)
t = StartDrawing(ImageOutput(img))
BitBlt_(t, 0, 0, DesktopWidth(0), DesktopHeight(0), dc, 0, 0, #SRCCOPY)
StopDrawing()
ReleaseDC_(0, dc)
SaveImage(img, "C:\temp\test.png", #PB_ImagePlugin_PNG)
Delay (500)
MoveWindow_(h,sx,WR\Top,wd,ht,#True)
EndIf
EndIf
EndIf
h = GetWindow_(h, #GW_HWNDNEXT)
Until h = 0
EndProcedure
GetDesktopWindows()
PureBasic! Purely the best 
-
American Ninja
- User

- Posts: 24
- Joined: Mon Jan 14, 2013 8:01 am
Re: Screenshot of desktop but not current window
Moving or changing the appearance of Calculator is *not* the answer, as it causes a visible change, and interrupts the user if he's working on it. A window can't just move when being clicked or typed on, so that's not the answer. Also, you can't move a maximized window, so that's not the answer. Recall that the foreground window may be maximized, and yet I still want to screenshot everything underneath it. Calculator was just an example, but in my first post I said the *foreground* window, whatever size or state that may be at the time.
I think idle's tip may be the answer, because PrintWindow can grab a window's image silently and without interruption. I'll look further into that avenue.
I think idle's tip may be the answer, because PrintWindow can grab a window's image silently and without interruption. I'll look further into that avenue.
- netmaestro
- PureBasic Bullfrog

- Posts: 8452
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Screenshot of desktop but not current window
You can use the PrintWindow api to have a window print its contents to a device context. Here I show you how to get the main background windows of your desktop drawn to an image, giving you the basic background. Simply do an EnumWindows to find the visible ones, have them add themselves to the image and ignore the window you don't want in the image. No hiding or flickering needed.
Code: Select all
Prototype.l pPrintWindow(hWnd.l, hDc.l, lFlags.l)
Global hLib.l = OpenLibrary(#PB_Any , "user32.dll")
Global PrintWindow_.pPrintWindow = GetFunction(hLib , "PrintWindow")
Procedure enummer(hwnd, lparam)
cn$ = Space(255)
wn$ = Space(255)
GetClassName_(hwnd, @cn$, 255)
GetWindowText_(hwnd, @wn$, 255)
If wn$ = "FolderView" And cn$ = "SysListView32"
PokeI(lparam, hwnd)
ProcedureReturn 0
Else
ProcedureReturn 1
EndIf
EndProcedure
win.i = 0
EnumChildWindows_(GetDesktopWindow_(), @enummer(), @win)
If win
ExamineDesktops()
CreateImage(0, DesktopWidth(0), DesktopHeight(0), 24)
hdc = StartDrawing(ImageOutput(0))
PrintWindow_(win, hdc, 0)
StopDrawing()
w = ImageWidth(0)/2
h = ImageHeight(0)/2
ResizeImage(0, w,h)
CreateImage(1, DesktopWidth(0), 30, 32|#PB_Image_Transparent)
hdc = StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_AlphaBlend)
PrintWindow_(FindWindow_("Shell_TrayWnd", #Null), hdc, 0)
StopDrawing()
ResizeImage(1, ImageWidth(1)/2, ImageHeight(1)/2)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawImage(ImageID(1),0,ImageHeight(0)-16)
StopDrawing()
OpenWindow(0,0,0,w,h,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(0,0,0,0,0,ImageID(0))
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
CloseLibrary(hLib)
BERESHEIT
Re: Screenshot of desktop but not current window
Hi
Code: Select all
ExamineDesktops()
Prototype.i ptPrintWindow(hWnd, hdc, flags)
OpenLibrary(1, "User32.dll")
PrintWindow.ptPrintWindow = GetFunction(1, "PrintWindow")
CreateImage(0, DesktopWidth(0), DesktopHeight(0), 32)
hWnd = FindWindow_("ProgMan", 0)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hdc = StartDrawing(ImageOutput(0))
PrintWindow(hWnd, hdc, 0)
StopDrawing()
CreateImage(1, DesktopWidth(0), 30,32)
hdc = StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_AlphaBlend)
PrintWindow(FindWindow_("Shell_TrayWnd", #Null), hdc, 0)
StopDrawing()
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaClip )
DrawImage(ImageID(1),0,DesktopHeight(0)-30)
StopDrawing()
FreeImage(1)
hWnd = GetTopWindow_(GetDesktopWindow_())
While hWnd
hWnd = GetWindow_(hWnd,#GW_HWNDNEXT)
If IsWindowVisible_(hWnd)
WTitle$ = Space(128)
GetWindowText_(hWnd,@WTitle$,128)
If WTitle$ <> "Calculator"
GetWindowRect_(hWnd,r.RECT)
If r\left > 0 And r\right > 0
CreateImage(1,r\right - r\left,r\bottom-r\top)
hdc = StartDrawing(ImageOutput(1))
PrintWindow(hWnd, hdc, 0)
StopDrawing()
Delay(50)
StartDrawing(ImageOutput(0))
DrawImage(ImageID(1),r\left,r\top)
StopDrawing()
EndIf
EndIf
EndIf
Wend
SaveImage(0,"e:\test2.bmp")
CloseLibrary(1)
Egypt my love
Re: Screenshot of desktop but not current window
Thanks NetMaestro and RASHAD.
Nice work.
Guess I'll learn a lot trying to figure how the magic works!
Nice work.
Guess I'll learn a lot trying to figure how the magic works!
DE AA EB
-
American Ninja
- User

- Posts: 24
- Joined: Mon Jan 14, 2013 8:01 am
Re: Screenshot of desktop but not current window
Rashad, that's close, but two problems... the first is that my desktop has a gray background but it's black in the BMP screenshot, and second is if I replace "Calculator" with "Untitled - Notepad" and put a maximized Notepad window at the foreground, then this line crashes:
The error is that the image width must be >0. Remember, Calculator was just an example... the code must work with any size foreground window, such as when maximized. Thanks for getting me this far, though!!!
Code: Select all
CreateImage(1,r\right - r\left,r\bottom-r\top)Re: Screenshot of desktop but not current window
- Fixed Z-Order of the captured windows
- No more dimensions restrictions
- Speed enhanced
- No more dimensions restrictions
- Speed enhanced
Code: Select all
ExamineDesktops()
Dim hnd(0)
Prototype.i ptPrintWindow(hWnd, hdc, flags)
OpenLibrary(1, "User32.dll")
PrintWindow.ptPrintWindow = GetFunction(1, "PrintWindow")
CreateImage(0, DesktopWidth(0), DesktopHeight(0), 32)
hWnd = FindWindow_("ProgMan", 0)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hdc = StartDrawing(ImageOutput(0))
PrintWindow(hWnd, hdc, 0)
StopDrawing()
hWnd = GetTopWindow_(GetDesktopWindow_())
While hWnd
hWnd = GetWindow_(hWnd,#GW_HWNDNEXT)
If IsWindowVisible_(hWnd)
x + 1
ReDim hnd(x)
hnd(x) = hWnd
EndIf
Wend
For i = x To 1 Step -1
WTitle$ = Space(128)
GetWindowText_(hnd(i),@WTitle$,128)
If WTitle$ <> "Calculator" And hnd(i) <> FindWindow_("Shell_TrayWnd", #Null)
GetWindowRect_(hnd(i),r.RECT)
CreateImage(1,r\right - r\left,r\bottom-r\top,32)
hdc = StartDrawing(ImageOutput(1))
PrintWindow(hnd(i), hdc, 0)
StopDrawing()
StartDrawing(ImageOutput(0))
DrawImage(ImageID(1),r\left,r\top)
StopDrawing()
EndIf
Next
CreateImage(1, DesktopWidth(0), 30,32)
hdc = StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_AlphaBlend)
PrintWindow(FindWindow_("Shell_TrayWnd", #Null), hdc, 0)
StopDrawing()
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaClip )
DrawImage(ImageID(1),0,DesktopHeight(0)-30)
StopDrawing()
FreeImage(1)
SaveImage(0,"e:\test2.bmp")
CloseLibrary(1)
Egypt my love
Re: Screenshot of desktop but not current window
- Better logic
- Much faster
# 1 :
# 2 :
- Much faster
# 1 :
Code: Select all
ExamineDesktops()
Prototype.i ptPrintWindow(hWnd, hdc, flags)
OpenLibrary(1, "User32.dll")
PrintWindow.ptPrintWindow = GetFunction(1, "PrintWindow")
CreateImage(0, DesktopWidth(0), DesktopHeight(0), 32)
hWnd = FindWindow_("ProgMan", 0)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hdc = StartDrawing(ImageOutput(0))
PrintWindow(hWnd, hdc, 0)
StopDrawing()
hWnd = GetTopWindow_(GetDesktopWindow_())
hWnd = GetWindow_(hWnd,#GW_HWNDLAST)
While hWnd
hWnd = GetWindow_(hWnd,#GW_HWNDPREV)
If IsWindowVisible_(hWnd)
WTitle$ = Space(128)
GetWindowText_(hWnd,@WTitle$,128)
If WTitle$ <> "Calculator" And hWnd <> FindWindow_("Shell_TrayWnd", #Null)
GetWindowRect_(hWnd,r.RECT)
CreateImage(1,r\right - r\left,r\bottom-r\top)
hdc = StartDrawing(ImageOutput(1))
PrintWindow(hWnd, hdc, 0)
StopDrawing()
Delay(50)
StartDrawing(ImageOutput(0))
DrawImage(ImageID(1),r\left,r\top)
StopDrawing()
EndIf
EndIf
Wend
CreateImage(1, DesktopWidth(0), 30,32)
hdc = StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_AlphaBlend)
PrintWindow(FindWindow_("Shell_TrayWnd", #Null), hdc, 0)
StopDrawing()
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaClip )
DrawImage(ImageID(1),0,DesktopHeight(0)-30)
StopDrawing()
FreeImage(1)
SaveImage(0,"e:\test2.bmp")
CloseLibrary(1)
Code: Select all
#CAPTUREBLT = $40000000
ExamineDesktops()
hWnd = FindWindow_("ProgMan", 0)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hWnd = GetWindow_(hWnd, #GW_CHILD)
hBitmap = CreateImage(0, DesktopWidth(0), DesktopHeight(0),32)
hdc = StartDrawing(ImageOutput(0))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0,DesktopWidth(0), DesktopHeight(0), GetWindowDC_(hWnd), 0, 0, #SRCCOPY | #CAPTUREBLT)
StopDrawing()
hWnd = GetTopWindow_(GetDesktopWindow_())
hWnd = GetWindow_(hWnd,#GW_HWNDLAST)
While hWnd
hWnd = GetWindow_(hWnd,#GW_HWNDPREV)
If IsWindowVisible_(hWnd)
WTitle$ = Space(128)
GetWindowText_(hWnd,@WTitle$,128)
If WTitle$ <> "Calculator" And hWnd <> FindWindow_("Shell_TrayWnd", #Null)
GetWindowRect_(hWnd,r.RECT)
hBitmap = CreateImage(1,r\right-r\left,r\bottom-r\top ,32)
hdc = StartDrawing(ImageOutput(1))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0,r\right-r\left,r\bottom-r\top , GetWindowDC_(hWnd), 0,0, #SRCCOPY | #CAPTUREBLT)
StopDrawing()
StartDrawing(ImageOutput(0))
DrawImage(ImageID(1),r\left,r\top)
StopDrawing()
EndIf
EndIf
Wend
hWnd = FindWindow_("Shell_TrayWnd", #Null)
hBitmap = CreateImage(1, DesktopWidth(0), 30,32)
hdc = StartDrawing(ImageOutput(1))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0,DesktopWidth(0), 30, GetWindowDC_(hWnd), 0, 0, #SRCCOPY| #CAPTUREBLT)
StopDrawing()
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaClip )
DrawImage(ImageID(1),0,DesktopHeight(0)-30)
StopDrawing()
FreeImage(1)
SaveImage(0,"e:\test2.bmp")
Egypt my love
-
American Ninja
- User

- Posts: 24
- Joined: Mon Jan 14, 2013 8:01 am
Re: Screenshot of desktop but not current window
Your #1 code seems okay but still shows my desktop as being black instead of gray. Looks like some sort of alpha issue, or bitdepth issue??? Thanks for persevering for me!!!RASHAD wrote:- Better logic
- Much faster
# 1 :
-
IdeasVacuum
- Always Here

- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Screenshot of desktop but not current window
If the app is only on your desktop and your desktop always has a grey wallpaper, then use the Box() command to paint the image grey before the window images are added to it. Otherwise, you will need to find the active wallpaper and draw that on your image first.Your #1 code seems okay but still shows my desktop as being black instead of gray. Looks like some sort of alpha issue, or bitdepth issue??? Thanks for persevering for me!!!
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Screenshot of desktop but not current window
The problem is with DrawImage() which is used for merging several images
Tested with PB 5.0 x86 - Win 7 x64
- No problem with FireFox maximized
Edit :Updated
Tested with PB 5.0 x86 - Win 7 x64
- No problem with FireFox maximized
Code: Select all
#CAPTUREBLT = $40000000
ExamineDesktops()
hWnd = FindWindow_("ProgMan", 0)
hBitmap = CreateImage(0, DesktopWidth(0), DesktopHeight(0),32)
hdc = StartDrawing(ImageOutput(0))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0,DesktopWidth(0), DesktopHeight(0), GetWindowDC_(hWnd), 0, 0, #SRCCOPY | #CAPTUREBLT)
StopDrawing()
hWnd = GetTopWindow_(GetDesktopWindow_())
hWnd = GetWindow_(hWnd,#GW_HWNDLAST)
While hWnd
hWnd = GetWindow_(hWnd,#GW_HWNDPREV)
If IsWindowVisible_(hWnd)
WTitle$ = Space(128)
GetWindowText_(hWnd,@WTitle$,128)
If WTitle$ <> "Calculator"And WTitle$ <> "Start" And hWnd <> FindWindow_("Shell_TrayWnd", #Null)
GetWindowRect_(hWnd,r.RECT)
hBitmap = CreateImage(1,r\right-r\left,r\bottom-r\top ,32)
hdc = StartDrawing(ImageOutput(1))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0,r\right-r\left,r\bottom-r\top , GetWindowDC_(hWnd), 0,0, #SRCCOPY | #CAPTUREBLT)
StopDrawing()
StartDrawing(ImageOutput(0))
;DrawingMode(#PB_2DDrawing_AlphaClip )
DrawImage(ImageID(1),r\left,r\top)
StopDrawing()
EndIf
EndIf
Wend
;
hWnd = FindWindow_("Shell_TrayWnd", #Null)
hBitmap = CreateImage(1, DesktopWidth(0), 30,32)
hdc = StartDrawing(ImageOutput(1))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0,DesktopWidth(0), 30, GetWindowDC_(hWnd), 0, 0, #SRCCOPY| #CAPTUREBLT)
StopDrawing()
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaClip )
DrawAlphaImage(ImageID(1),0,DesktopHeight(0)-30,255)
StopDrawing()
SaveImage(0,"e:\test2.bmp")
Last edited by RASHAD on Wed Jan 16, 2013 8:37 am, edited 1 time in total.
Egypt my love
-
American Ninja
- User

- Posts: 24
- Joined: Mon Jan 14, 2013 8:01 am
Re: Screenshot of desktop but not current window
Still not quite right... I now get an error of "Line: 22 - Image 'Width' is too small, should be > 0" for this line:
It returns 0 for both width and height of a window that isn't seen, so it seems to be picking up invisible windows. I tried to use "IsWindowVisible_(hwnd)" to trap it, but it still fails. Looking into it.....
And no, it doesn't show all windows here anyway. Just the foreground one, which is the opposite of the goal. The code you had above was better, because it worked except for the desktop color.
Code: Select all
hBitmap = CreateImage(1,r\right-r\left,r\bottom-r\top ,32)And no, it doesn't show all windows here anyway. Just the foreground one, which is the opposite of the goal. The code you had above was better, because it worked except for the desktop color.