请问printwindow这个api函数的原理是什么

gaoyagy123 2012-04-04 08:46:01
这个api函数是调用了什么命令,或者其他api函数而达到后台截图的目的的?如果不用这个函数能办到相同的方法么?我知道强制刷新窗口的方法是:
InvalidateRect hwnd, 0, 0
UpdateWindow hwnd
但是这样也不能达到后台截图的目的,有人知道这个api函数的内含么?
...全文
4735 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
神-气 2013-12-20
  • 打赏
  • 举报
回复
引用 16 楼 u011600672 的回复:
最近也做后台找图, 感觉 PrintWindow(hwnd, destinationDC, PW_CLIENTONLY); == BitBlt(destinationDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top, sourceDC, 0, 0, SRCCOPY);
这个只有在开启DWM的情况下才成立,XP,win7 Basic theme下不成立。
神-气 2013-12-20
  • 打赏
  • 举报
回复
引用 2 楼 Lactoferrin 的回复:
PrintWindow和WM_PRINT不同,WM_PRINT是合作式的,需要目标窗口的窗口过程实现对WM_PRINTCLIENT的响应 PrintWindow却不需要,只需要对方能响应WM_PAINT,它的大致过程如下 PrintWindow(NtUserPrintWindow)->xxxPrintWindow->(SetRedirectedWindow->CreateRedirectionBitmap)->xxxUpdateWindow->_GetDCEx->NtGdiBitBlt xxxPrintWindow首先调用SetRedirectedWindow创建一个重定向位图(CreateRedirectionBitmap),将该窗口的绘制重定向到这个位图并做初始化、格式转换工作,而不是通常情况下的主帧缓冲(如果是开了桌面组合则是dwm里面的离屏表面) 接下来调用xxxUpdateWindow,向目标发送WM_PAINT,此时窗口过程像窗口dc绘制将被重定位到重定向位图,因此dc不会由于被遮挡而被剪裁,不再依赖窗口的位置,内容可以全部保留在重定向位图 最后调用_GetDCEx->NtGdiBitBlt将目标窗口的dc的内容bitblt到你提供的dc 完了
神-气 2013-12-19
  • 打赏
  • 举报
回复
我也用这个函数来抓某个窗口,容易出现目标窗口不再重绘,抓下来的图有黑色块等情况。不知道怎么解决。
csuchao 2013-12-11
  • 打赏
  • 举报
回复
Lactoferrin研究果然够深入,这个貌似需要操作窗口内部的数据结构,想自己实现不太可能。
驱蚊器21 2013-08-10
  • 打赏
  • 举报
回复
最近也做后台找图, 感觉 PrintWindow(hwnd, destinationDC, PW_CLIENTONLY); == BitBlt(destinationDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top, sourceDC, 0, 0, SRCCOPY);
qwestw 2013-03-15
  • 打赏
  • 举报
回复
我也想知道 调用了PrintWindow之后 目标Window的刷新就有问题
LitNakeX 2012-04-24
  • 打赏
  • 举报
回复
我用 PrintWindow 做窗口录像,每次调用时窗口图像都会有很明显的迟滞;因为是录像,每秒钟要调用 20 多次 PrintWindow,被录像的窗口就特别卡
看 MSDN 上有句话说:
“Calling this function from a thread that manages interaction with the user interface could make the application appear to be unresponsive.”
以为是线程的问题,就单独开一个线程去调 PrintWindow,结果感觉没啥区别。

不知道有没有什么解决办法?
gaoyagy123 2012-04-05
  • 打赏
  • 举报
回复
还有就是printwindow好像一运行就肯定是截取窗口整个全图,如果是窗口比较大,那么这样一来就会比较卡,不像bitblt可以只截取部分区域
gaoyagy123 2012-04-05
  • 打赏
  • 举报
回复
就是一个后台找图程序,通过后台截取图像,然后分析图像数据来找图,但是我发现用printwindow找图后,出现很多问题:
1、因为图像在不停切换,如果用自己写的printwindow找图后就会出现画面残缺,不流畅等,方块状扭曲等等问题,
2、如果窗口被置于后台,那么好像在找图的时候程序运行非常慢,但是一把程序放在前台就没这个情况,
如果我用别人的找图插件,就没这个情况,所以我就奇怪别人或许不是用printwindow写的
Lactoferrin 2012-04-05
  • 打赏
  • 举报
回复
你程序干什么的
gaoyagy123 2012-04-05
  • 打赏
  • 举报
回复
会不会是因为频繁调用的问题?
Lactoferrin 2012-04-05
  • 打赏
  • 举报
回复
反正我用没事
gaoyagy123 2012-04-05
  • 打赏
  • 举报
回复
恩是的,我用vb嘿嘿, 因为用printwindow不知道为什么,截图的时候画面总会出现畸形扭曲,然后要过起码半秒才会慢慢恢复,但是我用别人的插件就没这回事,所以我想或许不是用的printwindow这个函数
Kaile 2012-04-05
  • 打赏
  • 举报
回复
为什么非要不用printwindow?

上海到北京坐飞机最快,你非要问除了坐飞机,还有哪个更快
Lactoferrin 2012-04-05
  • 打赏
  • 举报
回复
WM_PRINT和PrintWindow原理完全不同,WM_PRINT需要对方窗口过程明确响应WM_PRINTCLIENT
你用vb?
gaoyagy123 2012-04-05
  • 打赏
  • 举报
回复
我发现无论WM_print还是WM_PAINT都无法把其他进程的窗口图像重绘到wparam所携带的HDC中去,如果是本进程的窗口倒是可以做到,但是printwindow却是可以跨进程实现的,请问这中间是缺少了哪一步呢,为啥我不用printwindow就无法实现后台截图呢
Lactoferrin 2012-04-05
  • 打赏
  • 举报
回复
就这一种最方便
gaoyagy123 2012-04-05
  • 打赏
  • 举报
回复
楼上的很厉害啊,谢谢你写了那么多,我想问下,如果我不用printwindow,那么具体需要调用那些api函数才能达到这个后台截图的目的呢?后台截图只有printwindow这个办法么?能否详细说下,谢谢!
Lactoferrin 2012-04-04
  • 打赏
  • 举报
回复
PrintWindow和WM_PRINT不同,WM_PRINT是合作式的,需要目标窗口的窗口过程实现对WM_PRINTCLIENT的响应
PrintWindow却不需要,只需要对方能响应WM_PAINT,它的大致过程如下
PrintWindow(NtUserPrintWindow)->xxxPrintWindow->(SetRedirectedWindow->CreateRedirectionBitmap)->xxxUpdateWindow->_GetDCEx->NtGdiBitBlt
xxxPrintWindow首先调用SetRedirectedWindow创建一个重定向位图(CreateRedirectionBitmap),将该窗口的绘制重定向到这个位图并做初始化、格式转换工作,而不是通常情况下的主帧缓冲(如果是开了桌面组合则是dwm里面的离屏表面)
接下来调用xxxUpdateWindow,向目标发送WM_PAINT,此时窗口过程像窗口dc绘制将被重定位到重定向位图,因此dc不会由于被遮挡而被剪裁,不再依赖窗口的位置,内容可以全部保留在重定向位图
最后调用_GetDCEx->NtGdiBitBlt将目标窗口的dc的内容bitblt到你提供的dc

完了
Kaile 2012-04-04
  • 打赏
  • 举报
回复 1
Remarks
This function is similar to WM_PRINT

看MSDN

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧