Screenshot of desktop but not current window

Just starting out? Need help? Post your questions and find answers here.
American Ninja
User
User
Posts: 24
Joined: Mon Jan 14, 2013 8:01 am

Screenshot of desktop but not current window

Post by American Ninja »

Hi everyone, I have a question regarding a special type of screenshot. I know how to get a desktop screenshot, and a screenshot of just the active window; but I need to get a screenshot of the entire desktop *without* the current foreground window, as if it were invisible. All other windows should be present in the shot. Can't figure out a way to do it. Any ideas? I don't need code, I'm just after a conceptual approach that I could try. Hiding the window, or moving it, is no good as it causes a noticeable flicker. Thanks for any ideas. 8)

EDIT Here's what I'm trying to do... first image below shows several windows, and I want to take a screenshot of the entire desktop but *without* calculator included. The second image shows how I'd like my screenshot to look like.

Image Image
Last edited by American Ninja on Mon Jan 14, 2013 1:25 pm, edited 2 times in total.
Nituvious
Addict
Addict
Posts: 1031
Joined: Sat Jul 11, 2009 4:57 am
Location: United States

Re: Screenshot of desktop but not current window

Post by Nituvious »

Something like this?

Code: Select all

ExamineDesktops()
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)

UsePNGImageEncoder()
SaveImage(img, "D:\test.png", #PB_ImagePlugin_PNG)
[edit] sorry, just reread your post. I'm dumb :oops:
▓▓▓▓▓▒▒▒▒▒░░░░░
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Screenshot of desktop but not current window

Post by electrochrisso »

Nituvious wrote:Something like this?

Code: Select all

ExamineDesktops()
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)

UsePNGImageEncoder()
SaveImage(img, "D:\test.png", #PB_ImagePlugin_PNG)
[edit] sorry, just reread your post. I'm dumb :oops:
Not that dumb, why not use that code and use SetWindowState(#Window,#PB_Window_Minimize) before the capture, then SetWindowState(#Window,#PB_Window_Normal) after the capture.
Or it might be better to use HideWindow(#Window, #True/#False) instead.
PureBasic! Purely the best 8)
American Ninja
User
User
Posts: 24
Joined: Mon Jan 14, 2013 8:01 am

Re: Screenshot of desktop but not current window

Post by American Ninja »

I neglected to mention that my program has no window of its own, so there won't be a use for SetWindowState() or other window commands. The foreground window that I *don't* want to capture will be a third-party window.
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Screenshot of desktop but not current window

Post by electrochrisso »

American Ninja wrote:I neglected to mention that my program has no window of its own, so there won't be a use for SetWindowState() or other window commands. The foreground window that I *don't* want to capture will be a third-party window.
I was wondering about that, if you are on windows, if you know the handle to the window through the API, then use the ShowWindow_(#hWnd,#SW_SHOWMINIMIZED) and ShowWindow_(hWnd,#SW_SHOWNORMAL) or if this is not possible another idea would be to use AutoIT, which can use the name of the window, there is some PB stuff that uses the AutoIT2 dll on the forum somewhere.
PureBasic! Purely the best 8)
American Ninja
User
User
Posts: 24
Joined: Mon Jan 14, 2013 8:01 am

Re: Screenshot of desktop but not current window

Post by American Ninja »

ShowWindow is no good because it causes flicker and also re-arranges the taskbar buttons when the window hides. And the user will wonder where his window went that he was typing on.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Screenshot of desktop but not current window

Post by IdeasVacuum »

It's unusual for HideWindow/ShowWindow to cause flicker in my experience, so that issue may be limited to you in some way, either code or hardware.

Sounds long-winded but the alternative is mostly simple and can be performed in milliseconds:
1) Get the ScreenSize
2) Get the Wallpaper Setting (image, image arrangement)
3) Create a blank image, ScreenSize, draw the wallpaper on it
4) Verify the location and size of the window that should not be captured
5) Capture the screen regions around the window. For example, if the window is center screen, your app will capture 4 regions - above the window, either side, below the window. Draw these 4 captures onto your image.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
American Ninja
User
User
Posts: 24
Joined: Mon Jan 14, 2013 8:01 am

Re: Screenshot of desktop but not current window

Post by American Ninja »

Hiding a window (making it disappear) and then re-showing it, you're saying it's unnoticable? :shock:

Looking at your steps, it's similar to what I was planning, but how do I get the imagery UNDER where the window is? This imagery could be composed of lots of other windows from other apps (see first post where I put other windows under the foreground one that I *don't* want). I don't want just a blank space. You see, it's not so easy to accomplish.
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Screenshot of desktop but not current window

Post by electrochrisso »

American Ninja wrote:ShowWindow is no good because it causes flicker and also re-arranges the taskbar buttons when the window hides. And the user will wonder where his window went that he was typing on.
Here is an example, no flicker on my computer, using minimize and normal, so the takbar buttons should not be re-arranged.

Code: Select all

Procedure WindowCallback(Window, Message, wParam, lParam)
  Select Message
    Case #WM_CLOSE
      DestroyWindow_(Window)
    Case #WM_DESTROY
      PostQuitMessage_(0)
      Result  = 0
    Default
      Result  = DefWindowProc_(Window, Message, wParam, lParam)
  EndSelect
  ProcedureReturn Result
EndProcedure

#Style  = #WS_VISIBLE | #WS_CAPTION | #WS_SYSMENU
WindowClass.s  = "WindowClass_227B"
wc.WNDCLASSEX
wc\cbSize  = SizeOf(WNDCLASSEX)
wc\hbrBackground = CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE))
wc\hCursor = LoadCursor_(0, #IDC_ARROW)
wc\lpfnWndProc  = @WindowCallback()
wc\lpszClassName  = @WindowClass
RegisterClassEx_(@wc)

screenx = GetSystemMetrics_(#SM_CXSCREEN)/2-320/2
screeny = GetSystemMetrics_(#SM_CYSCREEN)/2-240/2

hWndMain  = CreateWindow_( WindowClass, "Test Window", #Style, screenx, screeny, 320, 240, 0, 0, 0, 0)

Delay (1000)
ShowWindow_(hWndMain,  #SW_MINIMIZE) 
Delay (1000)
ShowWindow_(hWndMain,  #SW_SHOWNORMAL) 
Delay (1000)
ShowWindow_(hWndMain,  #SW_MINIMIZE) 
Delay (1000)
ShowWindow_(hWndMain,  #SW_SHOWNORMAL) 
Delay (1000)
ShowWindow_(hWndMain,  #SW_MINIMIZE) 
Delay (1000)
ShowWindow_(hWndMain,  #SW_SHOWNORMAL) 

While GetMessage_(msg.MSG, #Null, 0, 0 )
  TranslateMessage_(msg)
  DispatchMessage_(msg)
Wend
PureBasic! Purely the best 8)
American Ninja
User
User
Posts: 24
Joined: Mon Jan 14, 2013 8:01 am

Re: Screenshot of desktop but not current window

Post by American Ninja »

electrochrisso, my program doesn't use a window... and besides, your window disappears from the screen, which is not the desire. I think you misunderstand my requirements. Look at the first post again, I've included images to show what I want to achieve. I think it's actually impossible now. :(
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Screenshot of desktop but not current window

Post by electrochrisso »

American Ninja wrote:electrochrisso, my program doesn't use a window... and besides, your window disappears from the screen, which is not the desire. I think you misunderstand my requirements. Look at the first post again, I've included images to show what I want to achieve. I think it's actually impossible now. :(
Yes I know you are not using a window you created, you are using the calculator for your example, here is another example that uses the calculator, I thought you wanted the window(calculator) out of the way when you take the screen-shot, this is what happens then reappears when that is done, all you need to do is work out the timing, this is the best I can think of for now.

Code: Select all

Procedure GetDesktopWindows()
  h = GetWindow_(GetDesktopWindow_(), #GW_CHILD)
  Repeat
    If IsWindowVisible_(h) = #True
      c$ = Space(999) : GetWindowText_(h, c$, 999)
      If c$ <> ""
        If c$ = "Calculator"
          ShowWindow_(h,  #SW_MINIMIZE) 
          Delay (2000)
          ShowWindow_(h,  #SW_SHOWNORMAL) 
        EndIf
      EndIf
    EndIf
    h = GetWindow_(h, #GW_HWNDNEXT)
  Until h = 0
EndProcedure

GetDesktopWindows()
PureBasic! Purely the best 8)
American Ninja
User
User
Posts: 24
Joined: Mon Jan 14, 2013 8:01 am

Re: Screenshot of desktop but not current window

Post by American Ninja »

Thanks but hiding is not the answer. It flashes the window (especially on a maximized window), moves the taskbar position of it, and gives the focus to another arbitrary window when it shouldn't. See in my second image in the first post how none of the windows have the focus? That's because Calculator still does, but it's not included in the screenshot. That's the goal.
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Screenshot of desktop but not current window

Post by electrochrisso »

I have added the code to take the screen shot with the calculator out of the way, then back again when done.

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"
          ShowWindow_(h,  #SW_SHOWMINNOACTIVE) 
          Delay (500)
          ExamineDesktops()
          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)
          ShowWindow_(h,  #SW_SHOWNORMAL) 
        EndIf
      EndIf
    EndIf
    h = GetWindow_(h, #GW_HWNDNEXT)
  Until h = 0
EndProcedure

GetDesktopWindows()
Last edited by electrochrisso on Mon Jan 14, 2013 2:57 pm, edited 1 time in total.
PureBasic! Purely the best 8)
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Screenshot of desktop but not current window

Post by electrochrisso »

American Ninja wrote:Thanks but hiding is not the answer. It flashes the window (especially on a maximized window), moves the taskbar position of it, and gives the focus to another arbitrary window when it shouldn't. See in my second image in the first post how none of the windows have the focus? That's because Calculator still does, but it's not included in the screenshot. That's the goal.
Not sure what is going on with your system but I get no flashing or taskbar shifting, as for the focus issue, you will have to do it IdeasVacuum way, it is possible with a little work, I might even have a go at it, but not tonight, it is late here and beddy-byes time for me. :)
PureBasic! Purely the best 8)
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Screenshot of desktop but not current window

Post by electrochrisso »

I have edited the last code and changed to ShowWindow_(h, #SW_SHOWMINNOACTIVE), this now makes sure the other windows on the desktop do not have focus before the screenshot, I am really off to bed now. :lol:
PureBasic! Purely the best 8)
Post Reply