Skip to content

Allow for capturing obscured windows #180

Open
@BanditTech

Description

@BanditTech

General information:

  • OS name: Windows
  • OS version: 10
  • OS architecture: 64 bits
  • Resolutions:
    • Monitor 1: 1920x1080
    • Monitor 2: 1920x1080
  • Python version: 3.8.3
  • MSS version: 6.0.0

Description of the warning/error

This is not related to an error message. This has to do with capturing obscured windows.

Other details

In order to capture an obscured window, a library I have been using in AHK which also uses dll capture has figured out how to do it. I understand that this is not written in python or c, but this code may be an assistance in understanding the steps he has done in order to utilize the GetDCEx call.

Essentially he does what seems to be two captures, which is not ideal, but it works. I was hoping that it would be possible to collaborate on implementing this feature into your library, or if you would rather use this code as a starting point:

Bind Window function to set and remember the window

Some of the code here is not really necessary. Mostly it is just having a static value saved in the class which can be assigned to a window handle. When performing further screenshots, this handle will be used the get the DC instead of the screen.

BindWindow(window_id:=0, set_exstyle:=0, get:=0)
{
  static id, old, Ptr:=A_PtrSize ? "UPtr" : "UInt"
  if (get)
    return, id
  if (window_id)
  {
    id:=window_id, old:=0
    if (set_exstyle)
    {
      WinGet, old, ExStyle, ahk_id %id%
      WinSet, Transparent, 255, ahk_id %id%
      Loop, 30
      {
      Sleep, 100
      WinGet, i, Transparent, ahk_id %id%
      }
      Until (i=255)
    }
  }
  else
  {
    if (old)
      WinSet, ExStyle, %old%, ahk_id %id%
    id:=old:=0
  }
}
Capturing the screenshot, determining if a window handle is present and using that instead
if (hBM) and !(w<1 or h<1)
{
  win:=DllCall("GetDesktopWindow", Ptr)
  hDC:=DllCall("GetWindowDC", Ptr,win, Ptr)
  mDC:=DllCall("CreateCompatibleDC", Ptr,hDC, Ptr)
  oBM:=DllCall("SelectObject", Ptr,mDC, Ptr,hBM, Ptr)
  DllCall("BitBlt",Ptr,mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
    , Ptr,hDC, "int",x, "int",y, "uint",0x00CC0020) ; |0x40000000)
  DllCall("ReleaseDC", Ptr,win, Ptr,hDC)
  if (id:=BindWindow(0,0,1))
    WinGet, id, ID, ahk_id %id%
  if (id)
  {
    WinGetPos, wx, wy, ww, wh, ahk_id %id%
    left:=x, right:=x+w-1, up:=y, down:=y+h-1
    left:=left<wx ? wx:left, right:=right>wx+ww-1 ? wx+ww-1:right
    up:=up<wy ? wy:up, down:=down>wy+wh-1 ? wy+wh-1:down
    x:=left, y:=up, w:=right-left+1, h:=down-up+1
  }
  if (id) and !(w<1 or h<1)
  {
    hDC2:=DllCall("GetDCEx", Ptr,id, Ptr,0, "int",3, Ptr)
    DllCall("BitBlt",Ptr,mDC,"int",x-zx,"int",y-zy,"int",w,"int",h
    , Ptr,hDC2, "int",x-wx, "int",y-wy, "uint",0x00CC0020) ; |0x40000000)
    DllCall("ReleaseDC", Ptr,id, Ptr,hDC2)
  }
  DllCall("SelectObject", Ptr,mDC, Ptr,oBM)
  DllCall("DeleteDC", Ptr,mDC)
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions