Page 3 of 3

Re: Screen Capture

Posted: Sun Mar 20, 2022 2:40 am
by BarryG
@doctorized, the extra captured pixels on the sides and bottom of the window are part of the actual window, because Windows 10 has invisible borders for touch-screen reasons. There's lots of complaints on StackOverflow about this, and that Microsoft shouldn't include them in the visible size calculations.

So the capture size is technically correct, but visually ugly. Whichever code you're using has to manually subtract the extra pixel widths and height to get only the actual visible window area.

Re: Screen Capture

Posted: Sun Mar 20, 2022 1:10 pm
by breeze4me
doctorized wrote: Sat Mar 19, 2022 10:11 pm In my case, "My computer" window is captured with some extra pixels. Why? See the image below. Win 10 Pro x64 fully updated
https://ibb.co/qdPggpj
Try this.

Code: Select all

;capture a piece of screen 
Procedure CaptureScreen(Left, Top, Width, Height)
  Protected dm.DEVMODE, BMPHandle
  Protected old, trgDC, srcDC = CreateDC_("DISPLAY", "", "", dm)
  
  If srcDC
    trgDC = CreateCompatibleDC_(srcDC)
    If trgDC
      BMPHandle = CreateCompatibleBitmap_(srcDC, Width, Height)
      If BMPHandle
        old = SelectObject_(trgDC, BMPHandle)
        BitBlt_(trgDC, 0, 0, Width, Height, srcDC, Left, Top, #SRCCOPY)
        SelectObject_(trgDC, old)
      EndIf
      DeleteDC_(trgDC)
    EndIf
    DeleteDC_(srcDC)
  EndIf
  
  ProcedureReturn BMPHandle 
EndProcedure 

#DWMWA_EXTENDED_FRAME_BOUNDS = 9

Procedure GetWindowRect_modified(hWnd, *rt.RECT)
  Protected Lib, DwmIsCompositionEnabled, DwmGetWindowAttribute, flag
  
  If *rt = 0 : ProcedureReturn 0 : EndIf
  
  GetWindowRect_(hWnd, *rt)
  
  If OSVersion() >= #PB_OS_Windows_Vista
    Lib = OpenLibrary(#PB_Any, "dwmapi.dll")
    If Lib
      DwmIsCompositionEnabled = GetFunction(Lib, "DwmIsCompositionEnabled")
      If DwmIsCompositionEnabled
        CallFunctionFast(DwmIsCompositionEnabled, @flag)
      EndIf
      If flag = 1
        DwmGetWindowAttribute = GetFunction(Lib, "DwmGetWindowAttribute")
        If DwmGetWindowAttribute
          CallFunctionFast(DwmGetWindowAttribute, hWnd, #DWMWA_EXTENDED_FRAME_BOUNDS, *rt, SizeOf(RECT))
        EndIf
      EndIf
      CloseLibrary(Lib)
    EndIf
  EndIf
  
  ProcedureReturn 1
EndProcedure

Procedure CaptureWindow(WindowName.s)
  Protected Image, ScreenCaptureAddress, WindowSize.RECT, WinHndl = FindWindow_(0, WindowName)
  If WinHndl
    GetWindowRect_modified(WinHndl, @WindowSize)
    ScreenCaptureAddress = CaptureScreen(WindowSize\Left, WindowSize\Top, WindowSize\Right - WindowSize\Left, WindowSize\Bottom - WindowSize\Top)
    If ScreenCaptureAddress
      Image = CreateImage(#PB_Any, WindowSize\Right - WindowSize\Left, WindowSize\Bottom - WindowSize\Top)
      If Image
        If StartDrawing(ImageOutput(Image))
          DrawImage(ScreenCaptureAddress, 0, 0)
          StopDrawing()
          SaveImage(Image, "Screenshot.bmp")
        EndIf
        FreeImage(Image)
      EndIf
      DeleteObject_(ScreenCaptureAddress)
    EndIf
  Else
    ProcedureReturn 0
  EndIf
  ProcedureReturn 1
EndProcedure

CaptureWindow("My Computer")

Re: Screen Capture

Posted: Mon Apr 18, 2022 11:35 am
by doctorized
Works great! Thank you!