本文代码中涉及到avicap32.dll的函数资料均来自因特网,已调试通过。现将调试中遇到的问题和心得记录如下,以备日后查阅,亦冀可供同好参考。
先放上代码,代码中的注释为本人所加。
Public Class Form1
'下面两个api函数及常量的声明从正常执行的VB6程序中拷贝过来,使用参数和返回值的类型原是long,执行报错,后改为integer
Private Declare Function capCreateCaptureWindow Lib "avicap32.dll" _
Alias "capCreateCaptureWindowA" ( _
ByVal lpszWindowName As String, _
ByVal dwStyle As Integer, _
ByVal x As Integer, _
ByVal y As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hWndParent As Integer, _
ByVal nID As Integer) As Integer
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" ( _
ByVal hwnd As Integer, _
ByVal wMsg As Integer, _
ByVal wParam As Integer, _
lParam As Integer) As Integer
Private Const WS_CHILD = &H40000000
Private Const WS_VISIBLE = &H10000000
Private Const WM_CAP_START = &H400
Private Const WM_CAP_DRIVER_CONNECT = (WM_CAP_START + 10)
Private Const WM_CAP_SET_PREVIEWRATE = (WM_CAP_START + 52)
Private Const WM_CAP_SET_PREVIEW = (WM_CAP_START + 50)
Private Preview_Handle As Long
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'使用capCreateCaptureWindow 函数可以创建一个AVICap的捕获窗口,并返回该窗口的句柄,之后通过三个SendMessage()函数向该句柄发送消息来实现连接摄像头、设置帧速、打开预览
Preview_Handle = capCreateCaptureWindow("Video", WS_CHILD + WS_VISIBLE, 2, 2, 320, 256, Me.Handle, 0) ‘vb.net引用窗体句柄使用me.handle
'WM_CAP_DRIVR_CONNECT消息实现捕获窗体与设备驱动间的连接
'WM_CAP_SET_PREVIEWRATE 消息设置预览模式下图像的帧速度
'WM_CAP_SET_PREVIEW消息打开或者关闭预览模式
SendMessage(Preview_Handle, WM_CAP_DRIVER_CONNECT, 0, 0)
SendMessage(Preview_Handle, WM_CAP_SET_PREVIEWRATE, 1, 0)
SendMessage(Preview_Handle, WM_CAP_SET_PREVIEW, 1, 0)
End Sub
End Class
在vb6时代,调用Win32 API就被视为神秘地带、自找麻烦,到了vb.net时代,更是不鼓励直接调用底层函数,以致连APIViewer都不提供了。但是遇到.net库中没有的功能却别无他法。
经过测试,vb.net对API调用的支持还是蛮好的,其中最大的问题是VS升级带来的数据类型的变化。比如vb6和vb.net都有的long类型定义就不相同。capCreateCaptureWindow()和SendMessage()函数的参数和返回值类型在vb6中都是long,在vb6下编译也妥妥的。代码原封拷贝到vb.net中就出问题了,提示如下:
“原因可能是托管的PInvoke 签名与非托管的目标签名不匹配。请检查PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。”
看了半天也不明白这个原因说了个啥,还以为在vb.net中此方案行不通。在查找解决办法时,突然“变量类型”这个词映入眼帘,哦,会不会是……
把long统统改为integer,又出错了,不过这次错误指向me.hwnd,将me.hwnd改为Me.Handle, OK!
花了大把时间,终于捅破这层窗户纸。
上面程序运行时还有一个问题,有时会提示“选择视频设备”,需要再次单击按钮,才可以显示摄像头视频。
本文介绍了如何在VB.NET中使用AVICap32.DLL函数库监控摄像头,详细讨论了API调用过程中的问题和解决办法,包括类型匹配错误和捕获窗口句柄的正确获取。通过示例代码展示了如何创建捕获窗口、连接摄像头、设置帧速和开启预览。
3085

被折叠的 条评论
为什么被折叠?



