Capture image from any window
Posted: Sun Jun 24, 2007 9:14 pm
It shows a list of your windows and let you capture screenshots from them. It works perfectly in Windows Vista, but in Windows XP there is an error; it will include other windows in the screenshot if they're over the window you capture... (Could anyone please help me fix this?)
Code: Select all
EnableExplicit
Procedure CaptureImage(hWnd=#False)
Protected hImage, hdc, ClientRect.RECT
If hWnd
GetClientRect_(hWnd,@ClientRect)
With ClientRect
If \bottom > 0
hImage = CreateImage(#PB_Any,\right,\bottom)
hdc = StartDrawing(ImageOutput(hImage))
BitBlt_(hdc,0,0,\right,\bottom,GetDC_(hWnd),0,0,#SRCCOPY)
;ReleaseDC_()
StopDrawing()
EndIf
EndWith
Else
;Capture desktop
EndIf
;GetDCEx_(hWnd,ClientRect,
;#DCX_INTERSECTUPDATE|#DCX_VALIDATE
ProcedureReturn hImage
EndProcedure
; Procedure ImageWindow(hWnd);,Width,Height)
;
;
; EndProcedure
Enumeration ;Windows
#Main
#Image
EndEnumeration
Enumeration ;Gadgets
#Main_WindowList
#Main_Capture
#Main_Close
#Image_Image
EndEnumeration
;Debug
Structure Image
ID.l
Width.l
Height.l
EndStructure
Global WindowCount, Image.Image, hWnd, Title.s{128}
Procedure EnumWindows(hWnd,lParam)
Protected Title.s{128}, windowIsOwned, windowStyle, NormalWindow
SendMessage_(hWnd,#WM_GETTEXT,128,@Title)
windowIsOwned = GetWindow_(hWnd,#GW_OWNER) <> 0
windowStyle = GetWindowLong_(hWnd,#GWL_EXSTYLE)
NormalWindow = #True
;Do not allow invisible processes.
If Not IsWindowVisible_(hWnd)
NormalWindow = #False
EndIf
;Window must have a caption
If Title = ""
NormalWindow = #False
EndIf
;Should not have a parent
If GetParent_(hWnd) <> 0
NormalWindow = #False
EndIf
; ;Don't allow unowned tool tips
; If (windowStyle | #WS_EX_TOOLWINDOW) <> 0 And Not windowIsOwned
; NormalWindow = #False
; EndIf
;
; ;Don't allow applications with owners
; If (windowStyle | #WS_EX_APPWINDOW) = 0 And windowIsOwned
; NormalWindow = #False
; EndIf
If NormalWindow
AddGadgetItem(#Main_WindowList,WindowCount,Title)
SetGadgetItemData(#Main_WindowList,WindowCount,hWnd)
WindowCount + 1
EndIf
ProcedureReturn #True
EndProcedure
OpenWindow(#Main,0,0,250,200,"Select window to capture",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(#Main))
ListViewGadget(#Main_WindowList,5,5,240,165)
ButtonGadget(#Main_Capture,5,175,100,20,"Capture")
ButtonGadget(#Main_Close,145,175,100,20,"Close")
EnumWindows_(@EnumWindows(),#Null)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
Break
Case #Image
CloseWindow(#Image)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #Main_Capture
If GetGadgetState(#Main_WindowList) > -1
hWnd = GetGadgetItemData(#Main_WindowList,GetGadgetState(#Main_WindowList))
Image\ID = CaptureImage(hWnd)
If Image\ID
Image\Width = ImageWidth(Image\ID)
Image\Height = ImageHeight(Image\ID)
GetWindowText_(hWnd,@Title,128)
OpenWindow(#Image,0,0,Image\Width,Image\Height,"Screenshot - "+Title,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(#Image))
ImageGadget(#Image_Image,0,0,Image\Width,Image\Height,ImageID(Image\ID))
Else
MessageRequester("Error","Unable to capture image, window may be minimized...",#MB_ICONINFORMATION)
EndIf
EndIf
Case #Main_Close
Break
EndSelect
EndSelect
ForEver