截图[ctypes.windll CreateDCFromHandle]

时间:2013-06-30 20:45:39

标签: python ctypes python-mss

我正在使用纯python(ctypes)创建一个截图模块,没有像win32,wx,QT这样的大型文件库......它必须管理多个屏幕(PIL和Pillow不能)。

我阻止的地方是在调用CreateDCFromHandle时,ctypes.windll.gdi32不知道这个函数。我看了win32源代码,受到启发,但没用。如评论中所述,MSDN中不存在此功能,因此我应该采取哪些更改来考虑其他屏幕?

这是适用于主监视器的代码,但不适用于其他代码:source code。 它在第35行阻塞。我尝试了很多组合,在这里和其他网站上寻找答案。但对我来说没有任何功能......它只是一个截图!

你有线索吗?

提前致谢:)


编辑,我找到了我的秘密!这是有效的代码:

srcdc = ctypes.windll.user32.GetWindowDC(0)
memdc = ctypes.windll.gdi32.CreateCompatibleDC(srcdc)
bmp = ctypes.windll.gdi32.CreateCompatibleBitmap(srcdc, width, height)
ctypes.windll.gdi32.SelectObject(memdc, bmp)
ctypes.windll.gdi32.BitBlt(memdc, 0, 0, width, height, srcdc, left, top, SRCCOPY)        
bmp_header = pack('LHHHH', calcsize('LHHHH'), width, height, 1, 24)
c_bmp_header = c_buffer(bmp_header) 
c_bits = c_buffer(' ' * (height * ((width * 3 + 3) & -4)))
got_bits = ctypes.windll.gdi32.GetDIBits(memdc, bmp, 0, height,
                        c_bits, c_bmp_header, DIB_RGB_COLORS)
# Here, got_bits should be equal to height to tell you all goes well.

法文文章及完整解释:Windows : capture d'écran

3 个答案:

答案 0 :(得分:1)

the source查看pywin32CreateDCFromHandle是捏造的。它在Windows API中不存在;它只是一个将Windows API事物转换为pywin32事物的桥梁。

由于您使用的是ctypes而不是pywin32,因此无需进行转换;看看你是否可以跳过这一步:

hwin = user.GetDesktopWindow()
hwindc = user.GetWindowDC(monitor['hmon'])
memdc = gdi.CreateCompatibleDC(hwindc)

当您尝试在Python中使用ctypes执行某些本机Windows API时,我发现查看已使用Windows API的现有C代码而不是使用使用包裹它。

答案 1 :(得分:1)

这不是Windows API函数。您需要EnumDisplayDevicesCreateDC的组合。请注意,必须在函数名称后附加“A”或“W”,具体取决于您是否要使用ANSI字符串或Unicode(widechar)字符串。

答案 2 :(得分:0)

编辑,我找到了我的秘密!这是有效的代码:

srcdc = ctypes.windll.user32.GetWindowDC(0)
memdc = ctypes.windll.gdi32.CreateCompatibleDC(srcdc)
bmp = ctypes.windll.gdi32.CreateCompatibleBitmap(srcdc, width, height)
ctypes.windll.gdi32.SelectObject(memdc, bmp)
ctypes.windll.gdi32.BitBlt(memdc, 0, 0, width, height, srcdc, left, top, SRCCOPY)        
bmp_header = pack('LHHHH', calcsize('LHHHH'), width, height, 1, 24)
c_bmp_header = c_buffer(bmp_header) 
c_bits = c_buffer(' ' * (height * ((width * 3 + 3) & -4)))
got_bits = ctypes.windll.gdi32.GetDIBits(
    memdc, bmp, 0, height, c_bits, c_bmp_header, DIB_RGB_COLORS)
# Here, got_bits should be equal to height to tell you all goes well.