有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

时间:2022-10-06 13:02:05
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

28 个解决方案

#1


主要就是 FindWindow、 GetDC、 BitBlt 这几个API。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?
如果它的图像是用DirectX接口画的,有可能“捕捉”不下来,那就再通过 桌面DC来BitBlt()就行了,
这就要用到另外的API:GetWindowRect、 GetDesktopWindow

#2


截屏,扣图。

#3


引用 1 楼 Chen8013 的回复:
主要就是 FindWindow、 GetDC、 BitBlt 这几个API。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?
如果它的图像是用DirectX接口画的,有可能“捕捉”不下来,那就再通过 桌面DC来BitBlt()就行了,
这就要用到另外的API:GetWindowRect、 GetDesktopWindow


可以捕捉的,别人的软件已经实现功能,我希望自己的软件也可以实现该功能。
求代码指导,谢谢

#4


无论如何,你的第一步必须是正确找到窗口句柄!

你先用Sp++或其它工具软件,先看看“图像”所在位置的区域,它的“窗口层次”关系。
然后从“上层”到“图像窗口”,逐级查找窗口。
如果它直接在一个简单窗口内,就用 FindWindow就能找到。
如果是多层嵌套的,就必须用到 FindWindowEx这个API才行。
关键的是“最顶层窗口”那一步,你必须注意它的窗口类名或窗口标题作为唯一特征,用来区分是否正确找到窗口。

#5


引用 4 楼 Chen8013 的回复:
无论如何,你的第一步必须是正确找到窗口句柄!

你先用Sp++或其它工具软件,先看看“图像”所在位置的区域,它的“窗口层次”关系。
然后从“上层”到“图像窗口”,逐级查找窗口。
如果它直接在一个简单窗口内,就用 FindWindow就能找到。
如果是多层嵌套的,就必须用到 FindWindowEx这个API才行。
关键的是“最顶层窗口”那一步,你必须注意它的窗口类名或窗口标题作为唯一特征,用来区分是否正确找到窗口。


那个窗体没有标题栏,只能通过窗口类名进行区分吗?

#6


没有标题栏,并不代表“没有窗口标题”。
用工具软件看了再说好不!!!!

你看我这个小程序,窗体是无边框的(Border为0,也就是“没有标题栏”)
它仍然是有“窗口标题”的!注意这个“标题”内容并不代表窗口左下的标签文本(虽然相同),而是窗口自身的“标题”。
窗口类名为 ThunderRT6FormDC,就说明这是个VB6的程序窗口!
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

#7


有个叫 《Visual Basic 6.0 开发宝典》的书,455页。捕捉屏幕图像,不过书上代码不太对。
我打出来的代码:http://pan.baidu.com/s/1gdrlcgr 可以运行,这个程序截取当前屏幕图像作为背景生成气泡图案。

#8


引用 6 楼 Chen8013 的回复:
没有标题栏,并不代表“没有窗口标题”。
用工具软件看了再说好不!!!!
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?


谢谢,可以查看到窗口的类,下一步呢?
请指教,

#9


引用 8 楼 lashengcrh 的回复:
.....................

谢谢,可以查看到窗口的类,下一步呢?
请指教,

这“下一步”要做的,我在4F已经给你说了啊!
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?

#10


这“下一步”要做的,我在4F已经给你说了啊!
有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?



    hwnd = FindWindow("Form2", "ThunderRT6FormDC")
    Call GetWindowRect(hwnd, rect2)
    objhDC = GetDC(hwnd)
    
    lhDC = CreateCompatibleDC(objhDC)
    If (lhDC <> 0) Then

        lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)
        If (lhBMP <> 0) Then

            lhBMPOld = SelectObject(lhDC, lhBMP)
       
            BitBlt lhDC, 0, 0, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY, objhDC, 0, 0, SRCCOPY
       
            SelectObject lhDC, lhBMPOld
             
            EmptyClipboard
            OpenClipboard 0
            SetClipboardData CF_BITMAP, lhBMP
            CloseClipboard
        End If
        DeleteObject lhDC
    End If

试着写了一下代码,没有效果,这方面不是很熟悉

#11


最后是用SavePicture Clipboard.GetData(vbCFBitmap), "C:\1.jpg" 将剪贴板内容保存到图片

由于上面的代码有问题,保存的图片都是空白。

#12



 lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)


GetWindowRect获得的Rect可以直接用,不必再除以Screen.TwipsPerPixelX了!!!

#13


引用 10 楼 lashengcrh 的回复:
这“下一步”要做的,我在4F已经给你说了啊!
有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?



    hwnd = FindWindow("Form2", "ThunderRT6FormDC")
    Call GetWindowRect(hwnd, rect2)
    objhDC = GetDC(hwnd)
    
    lhDC = CreateCompatibleDC(objhDC)
    If (lhDC <> 0) Then

        lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)
        If (lhBMP <> 0) Then

            lhBMPOld = SelectObject(lhDC, lhBMP)
       
            BitBlt lhDC, 0, 0, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY, objhDC, 0, 0, SRCCOPY
       
            SelectObject lhDC, lhBMPOld
             
            EmptyClipboard
            OpenClipboard 0
            SetClipboardData CF_BITMAP, lhBMP
            CloseClipboard
        End If
        DeleteObject lhDC
    End If

试着写了一下代码,没有效果,这方面不是很熟悉
你这代码至少有3个严重错误:
1.  FindWindow( )用法错误。
  第一个参数是“窗口类名”,第二个参数是“窗口名(窗口标题)”,你把参数值传反了!
2. If (lhDC <> 0) Then 这儿是有逻辑错误的!
  因为前面 hWnd =  FindWindow( ) 这儿,无论成功与否,
  后面的:objhDC = GetDC(lhWnd)和lhDC = CreateCompatibleDC(objhDC)总会成功的。
  (现在的电脑基本不会出现“系统资源不足”的情况吧!当然如果出现,系统也崩溃了)
  所以你以 (lhDC <> 0) 来判断,未必是你要的结果。
  因为 FindWindow( )成功,hWnd是你要找的窗口;如果失败,则返回值为0,hWnd就为0,
  objhDC = GetDC(lhWnd)时,如果前面 FindWindow( )成功,objhDC是你要找的窗口DC;
  而 FindWindow( )失败,hWnd为0时,objhDC的值是代表“桌面”的DC,
  所以objhDC肯定不会是0的,你的这个If语句没有起到预期的作用!
3. rect2的值由 GetWindowRect( )得到,你在后面使用时,应该直接使用它的成员值,
  不能再去除以TwipsPerPixelX、TwipsPerPixelY什么的!
  因为API中的尺寸单位基本上都是像素(注意,有一些API不是)。
  那些“配套的API”使用的单位总是一致的,不管它以什么为单位,都是不用转换的。

#14


晕,楼主在10楼的回复乱改脚本标记,造成我13F的回复,显示格式不对。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

引用 10 楼 lashengcrh 的回复:
这“下一步”要做的,我在4F已经给你说了啊!
有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?


    hwnd = FindWindow("Form2", "ThunderRT6FormDC")
    Call GetWindowRect(hwnd, rect2)
    objhDC = GetDC(hwnd)
    
    lhDC = CreateCompatibleDC(objhDC)
    If (lhDC <> 0) Then

        lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)
        If (lhBMP <> 0) Then

            lhBMPOld = SelectObject(lhDC, lhBMP)
       
            BitBlt lhDC, 0, 0, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY, objhDC, 0, 0, SRCCOPY
       
            SelectObject lhDC, lhBMPOld
             
            EmptyClipboard
            OpenClipboard 0
            SetClipboardData CF_BITMAP, lhBMP
            CloseClipboard
        End If
        DeleteObject lhDC
    End If

试着写了一下代码,没有效果,这方面不是很熟悉

你这代码至少有3个严重错误:
1.  FindWindow( )用法错误。
  第一个参数是“窗口类名”,第二个参数是“窗口名(窗口标题)”,你把参数值传反了!
2. If (lhDC <> 0) Then 这儿是有逻辑错误的!
  因为前面 hWnd =  FindWindow( ) 这儿,无论成功与否,
  后面的:objhDC = GetDC(lhWnd)和lhDC = CreateCompatibleDC(objhDC)总会成功的。
  (现在的电脑基本不会出现“系统资源不足”的情况吧!当然如果出现,系统也崩溃了)
  所以你以 (lhDC <> 0) 来判断,未必是你要的结果。
  因为 FindWindow( )成功,hWnd是你要找的窗口;如果失败,则返回值为0,hWnd就为0,
  objhDC = GetDC(lhWnd)时,如果前面 FindWindow( )成功,objhDC是你要找的窗口DC;
  而 FindWindow( )失败,hWnd为0时,objhDC的值是代表“桌面”的DC,
  所以objhDC肯定不会是0的,你的这个If语句没有起到预期的作用!
3. rect2的值由 GetWindowRect( )得到,你在后面使用时,应该直接使用它的成员值,
  不能再去除以TwipsPerPixelX、TwipsPerPixelY什么的!
  因为API中的尺寸单位基本上都是像素(注意,有一些API不是)。
  那些“配套的API”使用的单位总是一致的,不管它以什么为单位,都是不用转换的。

#15


代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

#16


引用 1 楼 Chen8013 的回复:
主要就是 FindWindow、 GetDC、 BitBlt 这几个API。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?
如果它的图像是用DirectX接口画的,有可能“捕捉”不下来,那就再通过 桌面DC来BitBlt()就行了,
这就要用到另外的API:GetWindowRect、 GetDesktopWindow


谢谢指点,现在已经可以抓取窗口。现在,我想抓取视频播放器的画面,提示捕获窗口失败,请问怎么办?

(因为我要截取的窗口是从摄像头显示的画面,很想播放器,所以我就拿播放器来测试了。)

#17


我使用了GetDesktopWindow获取了桌面句柄,可以将整个桌面截图。

请教,可以再精确到想要截图的那个窗口吗?

#18


引用 17 楼 lashengcrh 的回复:
我使用了GetDesktopWindow获取了桌面句柄,可以将整个桌面截图。

请教,可以再精确到想要截图的那个窗口吗?

我在1楼的回复中就说过了。 有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

既然已经找到了你要抓图的窗口的句柄,
那通过API函数:GetWindowRect() 或者 GetClientRect() 就可以计算出“画面”在桌面上的哪块区域了!
再用 BitBlt ,通过桌面DC把那一块抠下来,不就行了吗???

那个“精确位置”,是以GetWindowRect() 或者 GetClientRect()得到的数据为依据、按目标窗体的实际布局特征来计算的!
“目标窗体的实际布局特征”你是只字未提,我能说什么!!!!
要写程序,一点儿也不动脑筋、不会转点弯,那怎么行…………

#19


引用 18 楼 Chen8013 的回复:
Quote: 引用 17 楼 lashengcrh 的回复:

我使用了GetDesktopWindow获取了桌面句柄,可以将整个桌面截图。

请教,可以再精确到想要截图的那个窗口吗?

我在1楼的回复中就说过了。 有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

既然已经找到了你要抓图的窗口的句柄,
那通过API函数:GetWindowRect() 或者 GetClientRect() 就可以计算出“画面”在桌面上的哪块区域了!
再用 BitBlt ,通过桌面DC把那一块抠下来,不就行了吗???

那个“精确位置”,是以GetWindowRect() 或者 GetClientRect()得到的数据为依据、按目标窗体的实际布局特征来计算的!
“目标窗体的实际布局特征”你是只字未提,我能说什么!!!!
要写程序,一点儿也不动脑筋、不会转点弯,那怎么行…………



抱歉,那个窗口是从摄像头捕获视频的窗口,我的程序提示捕获窗口失败,请问怎么办?

#20


先用Spy++,看看它能不能成功获取窗口句柄。
然后,注意它的窗口类名是什么。

有一些用了“界面库”的应用程序,窗口内的子窗口有可能找不到,
但一般来说,“*窗口”都是能够找到句柄的。

#21


引用 20 楼 Chen8013 的回复:
先用Spy++,看看它能不能成功获取窗口句柄。
然后,注意它的窗口类名是什么。

有一些用了“界面库”的应用程序,窗口内的子窗口有可能找不到,
但一般来说,“*窗口”都是能够找到句柄的。


有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

spy可以读取到这个窗体信息,就是抓取时,提示“获取失败”,
我自己用vb制作了一个最顶层窗体,测试抓取也没问题,
奇怪,为什么图片上这个窗体就抓取不成功呢!

#22


你确认“图片上这个窗体”,是 顶层窗口吗?
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

#23


你要抓的那窗口句柄应该是这个吧:

hwnd = FindWindow("VideoRenderer",VBNullString)

#24


引用 22 楼 Chen8013 的回复:
你确认“图片上这个窗体”,是 顶层窗口吗?
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?


是的,要显示spy的界面,只能先将那个窗体拖动到旁边才行的!!

#25


该回复于2015-07-10 15:55:06被管理员删除

#26


引用 23 楼 Carlven2012 的回复:
你要抓的那窗口句柄应该是这个吧:

hwnd = FindWindow("VideoRenderer",VBNullString)

这代码,看起来没错啊。

引用 24 楼 lashengcrh 的回复:
是的,要显示spy的界面,只能先将那个窗体拖动到旁边才行的!!

我这儿说的“顶层”,不是说的位置关系,而是“逻辑层次”。
就是说,它要是从属于“桌面”的子窗口,才能用FindWindow( )来查找。

你还是贴张包含有那个窗口的桌面截图来看看吧。(要是那个“视频”画面有什么敏感内容,就把它抹掉吧  有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

#27


引用 26 楼 Chen8013 的回复:
Quote: 引用 23 楼 Carlven2012 的回复:

你要抓的那窗口句柄应该是这个吧:

hwnd = FindWindow("VideoRenderer",VBNullString)

这代码,看起来没错啊。

引用 24 楼 lashengcrh 的回复:
是的,要显示spy的界面,只能先将那个窗体拖动到旁边才行的!!

我这儿说的“顶层”,不是说的位置关系,而是“逻辑层次”。
就是说,它要是从属于“桌面”的子窗口,才能用FindWindow( )来查找。

你还是贴张包含有那个窗口的桌面截图来看看吧。(要是那个“视频”画面有什么敏感内容,就把它抹掉吧  有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?


看那画面,好像是偷拍的一个旅馆房间的画面! 我这是怎么了?

#28


还真有敏感内容啊………………

反正那个API的用法,已经给你说得很清楚了,你也“试验成功”过。
至于为何找那个视频窗口的句柄不能成功,要么你自己好好琢磨,
要么你就要提供足够详细的信息,让别人给你分析原因。 有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

#1


主要就是 FindWindow、 GetDC、 BitBlt 这几个API。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?
如果它的图像是用DirectX接口画的,有可能“捕捉”不下来,那就再通过 桌面DC来BitBlt()就行了,
这就要用到另外的API:GetWindowRect、 GetDesktopWindow

#2


截屏,扣图。

#3


引用 1 楼 Chen8013 的回复:
主要就是 FindWindow、 GetDC、 BitBlt 这几个API。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?
如果它的图像是用DirectX接口画的,有可能“捕捉”不下来,那就再通过 桌面DC来BitBlt()就行了,
这就要用到另外的API:GetWindowRect、 GetDesktopWindow


可以捕捉的,别人的软件已经实现功能,我希望自己的软件也可以实现该功能。
求代码指导,谢谢

#4


无论如何,你的第一步必须是正确找到窗口句柄!

你先用Sp++或其它工具软件,先看看“图像”所在位置的区域,它的“窗口层次”关系。
然后从“上层”到“图像窗口”,逐级查找窗口。
如果它直接在一个简单窗口内,就用 FindWindow就能找到。
如果是多层嵌套的,就必须用到 FindWindowEx这个API才行。
关键的是“最顶层窗口”那一步,你必须注意它的窗口类名或窗口标题作为唯一特征,用来区分是否正确找到窗口。

#5


引用 4 楼 Chen8013 的回复:
无论如何,你的第一步必须是正确找到窗口句柄!

你先用Sp++或其它工具软件,先看看“图像”所在位置的区域,它的“窗口层次”关系。
然后从“上层”到“图像窗口”,逐级查找窗口。
如果它直接在一个简单窗口内,就用 FindWindow就能找到。
如果是多层嵌套的,就必须用到 FindWindowEx这个API才行。
关键的是“最顶层窗口”那一步,你必须注意它的窗口类名或窗口标题作为唯一特征,用来区分是否正确找到窗口。


那个窗体没有标题栏,只能通过窗口类名进行区分吗?

#6


没有标题栏,并不代表“没有窗口标题”。
用工具软件看了再说好不!!!!

你看我这个小程序,窗体是无边框的(Border为0,也就是“没有标题栏”)
它仍然是有“窗口标题”的!注意这个“标题”内容并不代表窗口左下的标签文本(虽然相同),而是窗口自身的“标题”。
窗口类名为 ThunderRT6FormDC,就说明这是个VB6的程序窗口!
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

#7


有个叫 《Visual Basic 6.0 开发宝典》的书,455页。捕捉屏幕图像,不过书上代码不太对。
我打出来的代码:http://pan.baidu.com/s/1gdrlcgr 可以运行,这个程序截取当前屏幕图像作为背景生成气泡图案。

#8


引用 6 楼 Chen8013 的回复:
没有标题栏,并不代表“没有窗口标题”。
用工具软件看了再说好不!!!!
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?


谢谢,可以查看到窗口的类,下一步呢?
请指教,

#9


引用 8 楼 lashengcrh 的回复:
.....................

谢谢,可以查看到窗口的类,下一步呢?
请指教,

这“下一步”要做的,我在4F已经给你说了啊!
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?

#10


这“下一步”要做的,我在4F已经给你说了啊!
有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?



    hwnd = FindWindow("Form2", "ThunderRT6FormDC")
    Call GetWindowRect(hwnd, rect2)
    objhDC = GetDC(hwnd)
    
    lhDC = CreateCompatibleDC(objhDC)
    If (lhDC <> 0) Then

        lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)
        If (lhBMP <> 0) Then

            lhBMPOld = SelectObject(lhDC, lhBMP)
       
            BitBlt lhDC, 0, 0, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY, objhDC, 0, 0, SRCCOPY
       
            SelectObject lhDC, lhBMPOld
             
            EmptyClipboard
            OpenClipboard 0
            SetClipboardData CF_BITMAP, lhBMP
            CloseClipboard
        End If
        DeleteObject lhDC
    End If

试着写了一下代码,没有效果,这方面不是很熟悉

#11


最后是用SavePicture Clipboard.GetData(vbCFBitmap), "C:\1.jpg" 将剪贴板内容保存到图片

由于上面的代码有问题,保存的图片都是空白。

#12



 lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)


GetWindowRect获得的Rect可以直接用,不必再除以Screen.TwipsPerPixelX了!!!

#13


引用 10 楼 lashengcrh 的回复:
这“下一步”要做的,我在4F已经给你说了啊!
有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?



    hwnd = FindWindow("Form2", "ThunderRT6FormDC")
    Call GetWindowRect(hwnd, rect2)
    objhDC = GetDC(hwnd)
    
    lhDC = CreateCompatibleDC(objhDC)
    If (lhDC <> 0) Then

        lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)
        If (lhBMP <> 0) Then

            lhBMPOld = SelectObject(lhDC, lhBMP)
       
            BitBlt lhDC, 0, 0, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY, objhDC, 0, 0, SRCCOPY
       
            SelectObject lhDC, lhBMPOld
             
            EmptyClipboard
            OpenClipboard 0
            SetClipboardData CF_BITMAP, lhBMP
            CloseClipboard
        End If
        DeleteObject lhDC
    End If

试着写了一下代码,没有效果,这方面不是很熟悉
你这代码至少有3个严重错误:
1.  FindWindow( )用法错误。
  第一个参数是“窗口类名”,第二个参数是“窗口名(窗口标题)”,你把参数值传反了!
2. If (lhDC <> 0) Then 这儿是有逻辑错误的!
  因为前面 hWnd =  FindWindow( ) 这儿,无论成功与否,
  后面的:objhDC = GetDC(lhWnd)和lhDC = CreateCompatibleDC(objhDC)总会成功的。
  (现在的电脑基本不会出现“系统资源不足”的情况吧!当然如果出现,系统也崩溃了)
  所以你以 (lhDC <> 0) 来判断,未必是你要的结果。
  因为 FindWindow( )成功,hWnd是你要找的窗口;如果失败,则返回值为0,hWnd就为0,
  objhDC = GetDC(lhWnd)时,如果前面 FindWindow( )成功,objhDC是你要找的窗口DC;
  而 FindWindow( )失败,hWnd为0时,objhDC的值是代表“桌面”的DC,
  所以objhDC肯定不会是0的,你的这个If语句没有起到预期的作用!
3. rect2的值由 GetWindowRect( )得到,你在后面使用时,应该直接使用它的成员值,
  不能再去除以TwipsPerPixelX、TwipsPerPixelY什么的!
  因为API中的尺寸单位基本上都是像素(注意,有一些API不是)。
  那些“配套的API”使用的单位总是一致的,不管它以什么为单位,都是不用转换的。

#14


晕,楼主在10楼的回复乱改脚本标记,造成我13F的回复,显示格式不对。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

引用 10 楼 lashengcrh 的回复:
这“下一步”要做的,我在4F已经给你说了啊!
有什么问题、API参数有哪点不明白,自己要说清楚啊!
是你需要解答,还得像挤牙膏似的,反过来问你?


    hwnd = FindWindow("Form2", "ThunderRT6FormDC")
    Call GetWindowRect(hwnd, rect2)
    objhDC = GetDC(hwnd)
    
    lhDC = CreateCompatibleDC(objhDC)
    If (lhDC <> 0) Then

        lhBMP = CreateCompatibleBitmap(objhDC, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY)
        If (lhBMP <> 0) Then

            lhBMPOld = SelectObject(lhDC, lhBMP)
       
            BitBlt lhDC, 0, 0, (rect2.Right - rect2.Left) \ Screen.TwipsPerPixelX, (rect2.Bottom - rect2.Top) \ Screen.TwipsPerPixelY, objhDC, 0, 0, SRCCOPY
       
            SelectObject lhDC, lhBMPOld
             
            EmptyClipboard
            OpenClipboard 0
            SetClipboardData CF_BITMAP, lhBMP
            CloseClipboard
        End If
        DeleteObject lhDC
    End If

试着写了一下代码,没有效果,这方面不是很熟悉

你这代码至少有3个严重错误:
1.  FindWindow( )用法错误。
  第一个参数是“窗口类名”,第二个参数是“窗口名(窗口标题)”,你把参数值传反了!
2. If (lhDC <> 0) Then 这儿是有逻辑错误的!
  因为前面 hWnd =  FindWindow( ) 这儿,无论成功与否,
  后面的:objhDC = GetDC(lhWnd)和lhDC = CreateCompatibleDC(objhDC)总会成功的。
  (现在的电脑基本不会出现“系统资源不足”的情况吧!当然如果出现,系统也崩溃了)
  所以你以 (lhDC <> 0) 来判断,未必是你要的结果。
  因为 FindWindow( )成功,hWnd是你要找的窗口;如果失败,则返回值为0,hWnd就为0,
  objhDC = GetDC(lhWnd)时,如果前面 FindWindow( )成功,objhDC是你要找的窗口DC;
  而 FindWindow( )失败,hWnd为0时,objhDC的值是代表“桌面”的DC,
  所以objhDC肯定不会是0的,你的这个If语句没有起到预期的作用!
3. rect2的值由 GetWindowRect( )得到,你在后面使用时,应该直接使用它的成员值,
  不能再去除以TwipsPerPixelX、TwipsPerPixelY什么的!
  因为API中的尺寸单位基本上都是像素(注意,有一些API不是)。
  那些“配套的API”使用的单位总是一致的,不管它以什么为单位,都是不用转换的。

#15


代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

#16


引用 1 楼 Chen8013 的回复:
主要就是 FindWindow、 GetDC、 BitBlt 这几个API。
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?
如果它的图像是用DirectX接口画的,有可能“捕捉”不下来,那就再通过 桌面DC来BitBlt()就行了,
这就要用到另外的API:GetWindowRect、 GetDesktopWindow


谢谢指点,现在已经可以抓取窗口。现在,我想抓取视频播放器的画面,提示捕获窗口失败,请问怎么办?

(因为我要截取的窗口是从摄像头显示的画面,很想播放器,所以我就拿播放器来测试了。)

#17


我使用了GetDesktopWindow获取了桌面句柄,可以将整个桌面截图。

请教,可以再精确到想要截图的那个窗口吗?

#18


引用 17 楼 lashengcrh 的回复:
我使用了GetDesktopWindow获取了桌面句柄,可以将整个桌面截图。

请教,可以再精确到想要截图的那个窗口吗?

我在1楼的回复中就说过了。 有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

既然已经找到了你要抓图的窗口的句柄,
那通过API函数:GetWindowRect() 或者 GetClientRect() 就可以计算出“画面”在桌面上的哪块区域了!
再用 BitBlt ,通过桌面DC把那一块抠下来,不就行了吗???

那个“精确位置”,是以GetWindowRect() 或者 GetClientRect()得到的数据为依据、按目标窗体的实际布局特征来计算的!
“目标窗体的实际布局特征”你是只字未提,我能说什么!!!!
要写程序,一点儿也不动脑筋、不会转点弯,那怎么行…………

#19


引用 18 楼 Chen8013 的回复:
Quote: 引用 17 楼 lashengcrh 的回复:

我使用了GetDesktopWindow获取了桌面句柄,可以将整个桌面截图。

请教,可以再精确到想要截图的那个窗口吗?

我在1楼的回复中就说过了。 有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

既然已经找到了你要抓图的窗口的句柄,
那通过API函数:GetWindowRect() 或者 GetClientRect() 就可以计算出“画面”在桌面上的哪块区域了!
再用 BitBlt ,通过桌面DC把那一块抠下来,不就行了吗???

那个“精确位置”,是以GetWindowRect() 或者 GetClientRect()得到的数据为依据、按目标窗体的实际布局特征来计算的!
“目标窗体的实际布局特征”你是只字未提,我能说什么!!!!
要写程序,一点儿也不动脑筋、不会转点弯,那怎么行…………



抱歉,那个窗口是从摄像头捕获视频的窗口,我的程序提示捕获窗口失败,请问怎么办?

#20


先用Spy++,看看它能不能成功获取窗口句柄。
然后,注意它的窗口类名是什么。

有一些用了“界面库”的应用程序,窗口内的子窗口有可能找不到,
但一般来说,“*窗口”都是能够找到句柄的。

#21


引用 20 楼 Chen8013 的回复:
先用Spy++,看看它能不能成功获取窗口句柄。
然后,注意它的窗口类名是什么。

有一些用了“界面库”的应用程序,窗口内的子窗口有可能找不到,
但一般来说,“*窗口”都是能够找到句柄的。


有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

spy可以读取到这个窗体信息,就是抓取时,提示“获取失败”,
我自己用vb制作了一个最顶层窗体,测试抓取也没问题,
奇怪,为什么图片上这个窗体就抓取不成功呢!

#22


你确认“图片上这个窗体”,是 顶层窗口吗?
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

#23


你要抓的那窗口句柄应该是这个吧:

hwnd = FindWindow("VideoRenderer",VBNullString)

#24


引用 22 楼 Chen8013 的回复:
你确认“图片上这个窗体”,是 顶层窗口吗?
有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?


是的,要显示spy的界面,只能先将那个窗体拖动到旁边才行的!!

#25


该回复于2015-07-10 15:55:06被管理员删除

#26


引用 23 楼 Carlven2012 的回复:
你要抓的那窗口句柄应该是这个吧:

hwnd = FindWindow("VideoRenderer",VBNullString)

这代码,看起来没错啊。

引用 24 楼 lashengcrh 的回复:
是的,要显示spy的界面,只能先将那个窗体拖动到旁边才行的!!

我这儿说的“顶层”,不是说的位置关系,而是“逻辑层次”。
就是说,它要是从属于“桌面”的子窗口,才能用FindWindow( )来查找。

你还是贴张包含有那个窗口的桌面截图来看看吧。(要是那个“视频”画面有什么敏感内容,就把它抹掉吧  有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?

#27


引用 26 楼 Chen8013 的回复:
Quote: 引用 23 楼 Carlven2012 的回复:

你要抓的那窗口句柄应该是这个吧:

hwnd = FindWindow("VideoRenderer",VBNullString)

这代码,看起来没错啊。

引用 24 楼 lashengcrh 的回复:
是的,要显示spy的界面,只能先将那个窗体拖动到旁边才行的!!

我这儿说的“顶层”,不是说的位置关系,而是“逻辑层次”。
就是说,它要是从属于“桌面”的子窗口,才能用FindWindow( )来查找。

你还是贴张包含有那个窗口的桌面截图来看看吧。(要是那个“视频”画面有什么敏感内容,就把它抹掉吧  有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?


看那画面,好像是偷拍的一个旅馆房间的画面! 我这是怎么了?

#28


还真有敏感内容啊………………

反正那个API的用法,已经给你说得很清楚了,你也“试验成功”过。
至于为何找那个视频窗口的句柄不能成功,要么你自己好好琢磨,
要么你就要提供足够详细的信息,让别人给你分析原因。 有个程序,窗体显示实时图像,像搜索窗体那样浮动在最上面,想做个程序,截取那个窗体的画面,怎么实现?