Page 1 of 3
Screenshot of window isn't themed
Posted: Tue Mar 27, 2018 1:50 pm
by Dude
I'm using the code below to take a screenshot of a window, such as Calculator, but the theme doesn't get captured.

What's wrong?
Code: Select all
Procedure ScreenshotWindow(hWnd)
If IsWindow_(hWnd)
lib=OpenLibrary(#PB_Any,"user32.dll")
If lib And GetFunction(lib,"PrintWindow")
If GetWindowRect_(hWnd,win.RECT)
hImage=CreateImage(#PB_Any,win\right-win\left,win\bottom-win\top)
If hImage
hDC=StartDrawing(ImageOutput(hImage))
If hDC
CallFunction(lib,"PrintWindow",hWnd,hDC,0)
StopDrawing()
ReleaseDC_(hWnd,hDC)
EndIf
EndIf
EndIf
CloseLibrary(lib)
EndIf
EndIf
ProcedureReturn hImage
EndProcedure
Delay(2000)
winshot=ScreenshotWindow(GetForegroundWindow_())
SetClipboardImage(winshot)
Re: Screenshot of window isn't themed
Posted: Tue Mar 27, 2018 2:02 pm
by RSBasic
I don't have Windows 7 to test with the old calculator.
Can you try this code?
http://www.rsbasic.de/aktualisierung/wi ... stellen.pb
Re: Screenshot of window isn't themed
Posted: Tue Mar 27, 2018 9:22 pm
by Dude
Sorry, but that didn't help. It's not just Calculator anyway - look how there's no borders on folder windows (second image):

Re: Screenshot of window isn't themed
Posted: Tue Mar 27, 2018 9:26 pm
by RSBasic
Alternatively you can simulate Alt + Print key with keybd_event_() and use the copied screenshot from the clipboard.
Re: Screenshot of window isn't themed
Posted: Tue Mar 27, 2018 9:59 pm
by RASHAD
Hi Dude
This is how PrintWindow do
It copies what in the context area of the object not what is shown on the desktop
That means it can copy any object while it is not visible
Try
It works fine with the old calculator but it is not easy to get the handle for the new calculator (it is applicable but it is not what you asked for)
Code: Select all
#CAPTUREBLT = $40000000
RunProgram("Calc1.exe")
Repeat
hwnd = FindWindow_(0,"Calculator")
Until hwnd
Delay(1000)
GetWindowRect_(hwnd,r.RECT)
hBitmap = CreateImage(0,r\right-r\left,r\bottom-r\top)
hdc = StartDrawing(ImageOutput(0))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc,0,0,r\right-r\left,r\bottom-r\top, GetDC_(0),r\left,r\top, #SRCCOPY | #CAPTUREBLT)
StopDrawing()
ClearClipboard()
SetClipboardImage(0)
Re: Screenshot of window isn't themed
Posted: Wed Mar 28, 2018 9:56 am
by Dude
RSBasic wrote:Alternatively you can simulate Alt + Print key with keybd_event_() and use the copied screenshot from the clipboard.
Hi RSBasic, I don't want to do that because (a) it means the current clipboard contents get lost, and (b) the target window has to both have the focus
and be topmost (in the foreground).
Rashad, your code only works if the target window is topmost or has the focus. The code in my original post is exactly what I want, but it doesn't theme it. I guess I'll just have to make do with that.
Thanks anyway guys!

Re: Screenshot of window isn't themed
Posted: Wed Mar 28, 2018 1:26 pm
by chi
Have you tried
AeroShot yet? The source code is pretty straight forward too...
1) take screenshot with white background (popup window, white bkg)
2) take screenshot with black background (popup window, black bkg)
3) DifferentiateAlpha white and black image
Re: Screenshot of window isn't themed
Posted: Wed Mar 28, 2018 4:24 pm
by chi
Here is a quick hack...
AeroShot (PB Edition) moved to
http://www.purebasic.fr/english/viewtop ... 93#p520993
Re: Screenshot of window isn't themed
Posted: Wed Mar 28, 2018 6:21 pm
by CELTIC88
I think you can not draw a hidden window with its theme "aero"
Re: Screenshot of window isn't themed
Posted: Wed Mar 28, 2018 8:49 pm
by skywalk
Wow, I never noticed on Windows 10, PrintWindow(hW, hdc, 0) works fine for my drawn windows, but modern apps like Calculator are all black?
Thanks chi, your code works.

The other submissions are black or show the image directly behind "Calculator".
Re: Screenshot of window isn't themed
Posted: Wed Mar 28, 2018 9:10 pm
by nco2k
you could ask the app to give you its thumbnail:
Code: Select all
EnableExplicit
#DWM_TNP_RECTDESTINATION = $00000001
#DWM_TNP_OPACITY = $00000004
#DWM_TNP_VISIBLE = $00000008
#DWM_TNP_SOURCECLIENTAREAONLY = $00000010
Structure DWM_THUMBNAIL_PROPERTIES
dwFlags.l
rcDestination.RECT
rcSource.RECT
opacity.a
PB_Alignment.b[3]
fVisible.l
fSourceClientAreaOnly.l
EndStructure
Prototype.l DwmRegisterThumbnail_(hwndDestination, hwndSource, *phThumbnailId)
Prototype.l DwmQueryThumbnailSourceSize_(hThumbnail, *pSize)
Prototype.l DwmUpdateThumbnailProperties_(hThumbnailId, *ptnProperties)
Prototype.l DwmUnregisterThumbnail_(hThumbnailId)
Procedure DwmThumbnail(hwndSource, hwndDestination)
Protected LibraryPB, DwmRegisterThumbnail_.DwmRegisterThumbnail_, DwmQueryThumbnailSourceSize_.DwmQueryThumbnailSourceSize_, DwmUpdateThumbnailProperties_.DwmUpdateThumbnailProperties_, DwmUnregisterThumbnail_.DwmUnregisterThumbnail_, hThumbnailId, size.SIZE, dwm_thumbnail_properties.DWM_THUMBNAIL_PROPERTIES
LibraryPB = OpenLibrary(#PB_Any, "Dwmapi.dll")
If LibraryPB
DwmRegisterThumbnail_ = GetFunction(LibraryPB, "DwmRegisterThumbnail")
DwmQueryThumbnailSourceSize_ = GetFunction(LibraryPB, "DwmQueryThumbnailSourceSize")
DwmUpdateThumbnailProperties_ = GetFunction(LibraryPB, "DwmUpdateThumbnailProperties")
DwmUnregisterThumbnail_ = GetFunction(LibraryPB, "DwmUnregisterThumbnail")
If DwmRegisterThumbnail_ And DwmRegisterThumbnail_(hwndDestination, hwndSource, @hThumbnailId) = #S_OK
If DwmQueryThumbnailSourceSize_ And DwmQueryThumbnailSourceSize_(hThumbnailId, @size) = #S_OK
dwm_thumbnail_properties\dwFlags = #DWM_TNP_RECTDESTINATION | #DWM_TNP_OPACITY | #DWM_TNP_VISIBLE | #DWM_TNP_SOURCECLIENTAREAONLY
dwm_thumbnail_properties\rcDestination\right = size\cx
dwm_thumbnail_properties\rcDestination\bottom = size\cy
dwm_thumbnail_properties\opacity = 255
dwm_thumbnail_properties\fVisible = #True
If DwmUpdateThumbnailProperties_ And DwmUpdateThumbnailProperties_(hThumbnailId, @dwm_thumbnail_properties) = #S_OK
;...
EndIf
EndIf
;If DwmUnregisterThumbnail_
;DwmUnregisterThumbnail_(hThumbnailId)
;EndIf
EndIf
CloseLibrary(LibraryPB)
EndIf
EndProcedure
OpenWindow(0, 100, 100, 320, 240, "Source", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
SetWindowColor(0, RGB(63, 127, 255))
OpenWindow(1, 450, 100, 400, 350, "Destination", #PB_Window_SystemMenu)
SetWindowColor(1, RGB(255, 255, 255))
DwmThumbnail(WindowID(0), WindowID(1))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
there is probably a better way, but i think dwm is the way to go.
c ya,
nco2k
Re: Screenshot of window isn't themed
Posted: Wed Mar 28, 2018 9:59 pm
by chi
skywalk wrote:Thanks chi, your code works.

np, code above changed a little bit...
Re: Screenshot of window isn't themed
Posted: Thu Mar 29, 2018 12:15 am
by skywalk
Thanks nco2k, thumbnail() works like a charm
@chi - Your changes broke the modern calculator capture. All black again. Your earlier version still works.
I guess I'll read up on DwmUpdateThumbnailProperties.

Re: Screenshot of window isn't themed
Posted: Thu Mar 29, 2018 2:27 am
by chi
skywalk wrote:@chi - Your changes broke the modern calculator capture. All black again. Your earlier version still works.
Should be fixed now

Re: Screenshot of window isn't themed
Posted: Thu Mar 29, 2018 12:52 pm
by Dude
@nco2k: That thumbnail code is great!

Can it be used to put the thumbnail image on a gadget instead of a window? Or how can I put a borderless window inside another window to show the thumbnail?