如何在 Microsoft Access 表单上使用网络摄像头捕获?

Dat*_*boy 1 database excel webcam ms-access vba

我正在 Microsoft Access 2013 中设计一个数据库来存储工厂中发现的故障部件的记录。

我正在尝试在我的表单上实现一个按钮,用户可以单击以访问其设备的相机,以在表单中附加故障图片。用户在 Dell Latitude 5290 二合一上使用 Windows 10。

我尝试了在网上找到的代码,但它非常旧。https://www.developerfusion.com/thread/46191/how-to-capture-picture-using-webcam-in-vb60/

Eri*_*k A 6

我发现您在自己调整代码时遇到了麻烦,所以让我向您介绍为 VBA 调整代码的过程。

首先,我们将创建一个包含网络摄像头代码的表单,并向其添加所需的控件。控件是:

4 个按钮,称为 cmd1、cmd2、cmd3 和 cmd4,以及 1 个子窗体控件,称为 PicWebCam。我们使用子窗体来替换 PictureBox 对象,因为它在 Access 中不可用。

由于子窗体需要显示某些内容,我们在设计视图中创建了第二个窗体,并将记录选择器和导航按钮设置为 No。我们不向窗体添加控件,并使其足够小,使其没有滚动条。然后,我们将子窗体控件的源对象设置为我们刚刚创建的窗体。

然后,代码还使用了一个CommonDialog控件来让我们选择一个文件路径来保存图片。虽然这在 Windows + Access 的某些组合中可用,但我们不能依赖它,因此我们将改用 FileDialog。

为了获取文件路径,我们将以下代码添加到我们的表单模块中:

Function GetSavePath() As String
    Dim f As Object 'FileDialog
    Set f = Application.FileDialog(2) 'msoFileDialogSaveAs
    If f.Show <> 0 Then GetSavePath = f.SelectedItems(1)
End Function
Run Code Online (Sandbox Code Playgroud)

然后,我们复制粘贴初始声明(类型和声明函数语句),并进行 2 处调整:

  1. 由于我们要将它们放置在表单模块中,因此Public默认情况下需要删除所有私有的内容,并更改Private为非私有的内容。

  2. 由于我们希望与 64 位 Access 兼容(您说您不需要,但无论如何都要添加它),我们希望将PtrSafe关键字添加到所有外部函数,并将所有指针的类型从 更改LongLongPtr。这段代码出现在我们刚刚创建的函数之前。

Function GetSavePath() As String
    Dim f As Object 'FileDialog
    Set f = Application.FileDialog(2) 'msoFileDialogSaveAs
    If f.Show <> 0 Then GetSavePath = f.SelectedItems(1)
End Function
Run Code Online (Sandbox Code Playgroud)

现在,我们可以复制粘贴实际功能,并进行 2 处更改:

  1. 我们使用该GetSavePath函数来获取用户想要保存文件的路径,而不是常见的对话框控制代码。
  2. 取而代之的是PicWebCam.hWnd,我们使用PicWebCam.Form.hWnd获取要填充网络摄像头源的帧的 hWnd。
Const WS_CHILD As Long = &H40000000
Const WS_VISIBLE As Long = &H10000000

Const WM_USER As Long = &H400
Const WM_CAP_START As Long = WM_USER

Const WM_CAP_DRIVER_CONNECT As Long = WM_CAP_START + 10
Const WM_CAP_DRIVER_DISCONNECT As Long = WM_CAP_START + 11
Const WM_CAP_SET_PREVIEW As Long = WM_CAP_START + 50
Const WM_CAP_SET_PREVIEWRATE As Long = WM_CAP_START + 52
Const WM_CAP_DLG_VIDEOFORMAT As Long = WM_CAP_START + 41
Const WM_CAP_FILE_SAVEDIB As Long = WM_CAP_START + 25

Private Declare PtrSafe Function capCreateCaptureWindow _
    Lib "avicap32.dll" Alias "capCreateCaptureWindowA" _
         (ByVal lpszWindowName As String, ByVal dwStyle As Long _
        , ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long _
        , ByVal nHeight As Long, ByVal hwndParent As LongPtr _
        , ByVal nID As Long) As Long

Private Declare PtrSafe Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hWnd As LongPtr, ByVal wMsg As Long _
        , ByVal wParam As Long, ByRef lParam As Any) As Long

Dim hCap As LongPtr
Run Code Online (Sandbox Code Playgroud)

最后,由于我们为Form_Load事件添加了事件处理程序,我们需要确保On Load表单的属性设置为[Event Procedure]On Click我们添加的所有命令按钮的属性也是如此。

而且,就是这样,我们已经成功地将网络摄像头代码从 VB6 迁移到 VBA,并重新创建了您提供的链接中稀疏描述的表单。大部分代码都归功于该链接上的作者。

您可以在此处临时下载结果。请注意,我建议您不要这样做,这既是出于教育目的,也是因为您不应该相信互联网上的随机陌生人为您提供未签名的可执行文件。但是如果您遇到错误,它会很有用,因此您可以检查它是否可能是网络摄像头兼容性问题或错误。

请注意,我没有对原始代码进行任何真正的功能更改。