VB实现USB摄像头视频图像的监控、截图、录像

前端之家收集整理的这篇文章主要介绍了VB实现USB摄像头视频图像的监控、截图、录像前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
本程序用四个按钮实现对摄像头视频的监控、截图、录像,可以分别保存为图片文件和视频文件。保存的视频文件可以用媒体播放机(Windows Media Player)、 暴风影音等软件进行播放,轻松实现家庭录像制作。
  利用电脑配备的 USB 摄像头进行视频控制,要用到两个 API 函数:capCreateCaptureWindow 和 SendMessage。
  capCreateCaptureWindow 的作用是创建一个视频窗口,摄像头捕捉到的视频图像在此窗口内显示函数返回值就是代表此窗口的句柄。此函数的 VB 声明:
Private Declare 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 Long,ByVal nID As Long) As Long
Dim ctCapWin As Long
  各参数意义如下:
lpszWindowName 视频窗口的窗口标题
dwStyle 窗口模式,设置值可用下面数值,也可组合使用:
WS_Child:视频窗口是子窗口,位于应用程序主窗口内。否则是独立的窗口。
WS_Visible:视频窗口可见
WS_Caption:视频窗口有标题
WS_ThickFrame:视频窗口有边框
X 视频窗口位置x坐标
Y 视频窗口位置y坐标
nWidth 视频窗口宽度
nHeight 视频窗口高度
hwndParent 创建视频窗口的主窗口,设置为:Me.hWnd
nID 视频ID

视频窗口创建后,剩下的事情就是用 SendMessage 向该窗口发送各种消息,实现对摄像头的控制。

  1. ' '以下是完整代码,在 VB6 WindowsXP 下调试通过:
  2. '在窗体放置4个控件:Command1、Command2、Command3、Command4
  3. ' 程序调试时要注意:终止程序要用运行中的 Form1 窗口关闭。不要使用 VB 主窗口的菜单命令或 VB 工具栏上的关闭按钮,这样无法关闭打开的视频窗口,导致 VB 无响应。如果 VB 无响应,只有用系统任务管理器才能终止 VB 进程,调试过程中所做的修改将丢失。
  4. '本人原创,转载请注明来源:http://hi.baidu.com/100bd/blog/item/52c7978a9b3cdf719f2fb4a5.html
  5. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,lParam As Any) As Long
  6. Private Declare Function capCreateCaptureWindow Lib "avicap32.dll" Alias "capCreateCaptureWindowA" (ByVal lpszWindowName As String,ByVal nID As Long) As Long
  7. Dim ctCapWin As Long,ctAviPath As String,ctPicPath As String,ctConnect As Boolean
  8. '视频窗口控制消息常数
  9. Const WS_Child = &H40000000: Const WS_Visible = &H10000000
  10. Const WS_Caption = &HC00000: Const WS_ThickFrame = &H40000
  11. Const WM_User = &H400 '用户消息开始号
  12. Const WM_CAP_Connect = WM_User + 10 '连接一个摄像头
  13. Const WM_CAP_DisConnect = WM_User + 11 '断开一个摄像头的连接
  14. Const WM_CAP_Set_PreView = WM_User + 50 '使预览模式有效或者失效
  15. Const WM_CAP_Set_Overlay = WM_User + 51 '使窗口处于叠加模式,也会自动地使预览模式失效。
  16. Const WM_CAP_Set_PreViewRate = WM_User + 52 '设置在预览模式下帧的显示频率
  17. Const WM_CAP_Edit_Copy = WM_User + 30 '将当前图像复制到剪贴板
  18. Const WM_CAP_Sequence = WM_User + 62 '开始录像,录像未结束前不会返回。
  19. Const WM_Cap_File_Set_File = WM_User + 20 '设置当前的视频捕捉文件
  20. Const WM_Cap_File_Get_File = WM_User + 21 '得到当前的视频捕捉文件
  21.  
  22.  
  23. Private Sub Form_Load()
  24. '设置按钮及位置,实际可以在控件设计期间完成
  25. Dim H1 As Long
  26. Me.Caption = "摄像头控制"
  27. Command1.Caption = "连接": Command1.ToolTipText = "连接摄像头"
  28. Command2.Caption = "断开": Command2.ToolTipText = "断开与摄像头的连接"
  29. Command3.Caption = "截图": Command3.ToolTipText = "将当前图像保存为图片文件"
  30. Command4.Caption = "录像": Command4.ToolTipText = "开始录像,保存为视频文件"
  31.  
  32.  
  33. H1 = Me.TextHeight("A")
  34. Command1.Move H1 * 0.5,H1 * 0.5,H1 * 4,H1 * 2
  35. Command2.Move H1 * 5,H1 * 2
  36. Command3.Move H1 * 10,H1 * 2
  37. Command4.Move H1 * 15,H1 * 2
  38. '读出用户设置
  39. Call ReadSaveSet
  40. KjEnabled True
  41. End Sub
  42.  
  43.  
  44. Private Sub Command1_Click()
  45. '创建视频窗口和连接摄像头
  46. Dim nStyle As Long,T As Long
  47. If ctCapWin = 0 Then '创建一个视频窗口,大小:640*480
  48. T = Me.ScaleY(Command1.Top + Command1.Height * 1.1,Me.ScaleMode,3) '视频窗口垂直位置:像素
  49. 'nStyle = WS_Child + WS_Visible + WS_Caption + WS_ThickFrame '子窗口(在Form1内)+可见+标题栏+边框
  50. nStyle = WS_Child + WS_Visible '视频窗口无标题栏和边框
  51. 'nStyle = WS_Visible '视频窗口为独立窗口,关闭主窗口视频窗口也会自动关闭
  52. ctCapWin = capCreateCaptureWindow("我创建的视频窗口",nStyle,T,640,480,Me.hWnd,0)
  53. End If
  54. '将视频窗口连接到摄像头,如无后面两条语句视频窗口画面不会变化
  55. SendMessage ctCapWin,WM_CAP_Connect,0 '连接摄像头
  56. SendMessage ctCapWin,WM_CAP_Set_PreView,1,0 '第三个参数:1-预览模式有效,0-预览模式无效
  57. SendMessage ctCapWin,WM_CAP_Set_PreViewRate,30,0 '第三个参数:设置预览显示频率为每秒 30
  58. ctConnect = True: KjEnabled True
  59. '"请检检查摄像头连接,并确定没有其他用户和程序使用。"
  60. End Sub
  61.  
  62.  
  63. Private Sub Command2_Click()
  64. SendMessage ctCapWin,WM_CAP_DisConnect,0 '断开摄像头连接
  65. ctConnect = False: KjEnabled True
  66. End Sub
  67.  
  68.  
  69. Private Sub Command3_Click()
  70. '截图,保存为图片文件
  71. Dim F As String,S As Long,nPath As String,nStr As String
  72. nPath = Trim(ctPicPath)
  73. If nPath = "" Then nPath = App.Path & "\MyPic"
  74. If Right(nPath,1) <> "" Then nPath = nPath & ""
  75. On Error Resume Next
  76. Do
  77. S = S + 1
  78. F = nPath & "MyPic-" & S & ".bmp"
  79. If Dir(F,23) = "" Then Exit Do
  80. Loop
  81. On Error GoTo 0
  82. nStr = Trim(InputBox("设置图片保存的文件名:","保存图片",F))
  83. If nStr = "" Then Exit Sub
  84. Call CutPathFile(nStr,nPath,F) '分解出文件和目录
  85. If Not MakePath(nPath) Then
  86. MsgBox "在指定的位置无法建立目录:" & vbCrLf & nPath,vbInformation,"保存图片文件"
  87. Exit Sub
  88. End If
  89. ctPicPath = nPath: F = nPath & F
  90. If Dir(F,23) <> "" Then
  91. If vbCancel = MsgBox("文件已存在,覆盖此文件吗?" & vbCrLf & F,vbInformation + vbOKCancel,"截图 - 文件覆盖") Then Exit Sub
  92. On Error GoTo Cuo
  93. SetAttr F,0
  94. Kill F
  95. On Error GoTo 0
  96. End If
  97. Clipboard.Clear: SendMessage ctCapWin,WM_CAP_Edit_Copy,0 '将当前图像复制到剪贴板
  98. SavePicture Clipboard.GetData,F '保存为 Bmp 图像,要保存为 jpg 格式,参见: 图片保存或转变为JPG格式
  99. Exit Sub
  100. Cuo:
  101. MsgBox "无法写文件:" & vbCrLf & F,"保存文件"
  102. End Sub
  103.  
  104.  
  105. Private Sub Command4_Click()
  106. '用摄像头录像,并保存为视频文件
  107. '如果不设置文件路径和名称,或路径不存在,视频窗口会使用默认文件 C:\CAPTURE.AVI
  108. Dim F As String,nStr As String
  109. nPath = Trim(ctAviPath)
  110. If nPath = "" Then nPath = App.Path & "\MyVideo"
  111. If Right(nPath,1) <> "" Then nPath = nPath & ""
  112. On Error Resume Next
  113. Do
  114. S = S + 1
  115. F = nPath & "MyVideo-" & S & ".avi"
  116. If Dir(F,23) = "" Then Exit Do
  117. Loop
  118. On Error GoTo 0
  119. nStr = Trim(InputBox("设置录像保存的文件名:","录像保存的文件名","保存文件"
  120. Exit Sub
  121. End If
  122. ctAviPath = nPath: F = nPath & F
  123. If Dir(F,"视频 - 文件覆盖") Then Exit Sub
  124. On Error GoTo Cuo
  125. SetAttr F,0
  126. Kill F
  127. On Error GoTo 0
  128. End If
  129. Me.Caption = "摄像头控制 - 正在录像(任意位置单击鼠标停止)": KjEnabled False: DoEvents
  130. SendMessage ctCapWin,WM_Cap_File_Set_File,ByVal F '设置录像保存的文件
  131. SendMessage ctCapWin,WM_CAP_Sequence,0 '开始录像。录像未结束前不会返回
  132. Me.Caption = "摄像头控制": KjEnabled True
  133. Exit Sub
  134. Cuo:
  135. MsgBox "无法写文件:" & vbCrLf & F,"保存文件"
  136. End Sub
  137.  
  138.  
  139. Private Function CutPathFile(nStr As String,nFile As String)
  140. '分解出文件和目录
  141. Dim I As Long,S As Long
  142. For I = 1 To Len(nStr)
  143. If Mid(nStr,I,1) = "" Then S = I '查找最后一个目录分隔符
  144. Next
  145. If S > 0 Then
  146. nPath = Left(nStr,S): nFile = Mid(nStr,S + 1)
  147. Else
  148. nPath = "": nFile = nStr
  149. End If
  150. End Function
  151.  
  152.  
  153. Private Function MakePath(ByVal nPath As String) As Boolean
  154. '逐级建立目录,成功返回 T
  155. Dim I As Long,Path1 As String,IsPath As Boolean
  156. nPath = Trim(nPath)
  157. If Right(nPath,1) <> "" Then nPath = nPath & ""
  158. On Error GoTo Exit1
  159. For I = 1 To Len(nPath)
  160. If Mid(nPath,1) = "" Then
  161. Path1 = Left(nPath,I - 1)
  162. If Dir(Path1,23) = "" Then
  163. MkDir Path1
  164. Else
  165. IsPath = GetAttr(Path1) And 16
  166. If Not IsPath Then Exit Function '有一个同名的文件
  167. End If
  168. End If
  169. Next
  170. MakePath = True: Exit Function
  171. Exit1:
  172. End Function
  173.  
  174.  
  175. Private Sub Form_Unload(Cancel As Integer)
  176. Call ReadSaveSet(True) '保存用户设置
  177. End Sub
  178.  
  179.  
  180. Private Sub KjEnabled(nEnabled As Boolean)
  181. If nEnabled Then
  182. Command1.Enabled = Not ctConnect: Command2.Enabled = ctConnect
  183. Command3.Enabled = ctConnect: Command4.Enabled = ctConnect
  184. Else
  185. Command1.Enabled = nEnabled: Command2.Enabled = nEnabled
  186. Command3.Enabled = nEnabled: Command4.Enabled = nEnabled
  187. End If
  188. End Sub
  189.  
  190.  
  191. Private Sub ReadSaveSet(Optional IsSave As Boolean)
  192. '保存或读出用户设置的图片和视频默认保存目录
  193. Dim nKey As String,nSub As String
  194. nKey = "摄像头控制程序": nSub = "UserOpt"
  195. If IsSave Then
  196. SaveSetting nKey,nSub,"AviPath",ctAviPath
  197. SaveSetting nKey,"PicPath",ctPicPath
  198. Else
  199. ctAviPath = GetSetting(nKey,"")
  200. ctPicPath = GetSetting(nKey,"")
  201. End If
  202. End Sub

下面程序是“实现USB摄像头视频图像的监控、截图、录像”的改进。可实现对摄像头视频的监控、截图、录像,可以分别保存为图片文件和视频(压缩)文件。保存的视频文件可以用媒体播放机(Windows Media Player)、 暴风影音等软件进行播放,轻松实现家庭录像制作。
   利用电脑配备的 USB 摄像头进行视频控制,要用到两个 API 函数:capCreateCaptureWindow 和 SendMessage。其中,capCreateCaptureWindow 的作用是创建一个视频窗口,摄像头捕捉到的视频图像在此窗口内显示函数返回值就是代表此窗口的句柄。视频窗口创建后,剩下的事情就是用 SendMessage 向该窗口发送各种消息,实现对摄像头的控制。

  本程序特点主要有:
  1.实现对摄像头视频图像的监控、截图,视频录像并保存为磁盘文件
  2.可控制多个视频摄像头。例如,如果一台电脑配置了两个摄像头,启动本程序两次,单击按钮“源”,在弹出的“视频源”对话框中选择不同的捕获源,两个窗口就能同时显示不同摄像头获得的图像。如下图所示:
  3.在“视频源”对话框中,还可以设置视频的亮度、对比度等许多参数
  4.录像时,如果采用默认的 AVI 文件格式,得到的视频文件会很大。单击按钮“压”,在弹出的“视频压缩”对话框中选择压缩方式“MPEG-4”,这样得到的视频文件会比默认方式小 10 倍以上。
  5.本程序的视频窗口有自动大小和全屏功能。在全屏状态时,工具栏会自动隐藏。将鼠标移动到屏幕顶部,工具栏又会自动显示出来。

   遗憾的是,由于水平有限,本程序无法判断是否使用了压缩记录方式,压缩后的文件其扩展名仍然是 AVI。当然,这并不影响播放,录像完成后也可以手动将扩展名修改为 mpg。其次,录像状态下改变视频窗口大小,有时会出现莫名其妙的错误。这个错误时有时无,毫无规律,因此本程序不得不关闭了录像状态下视频窗口自动大小 的功能

  1. ' '以下是窗体 Form1 的完整代码,在 VB6 WindowsXP 下调试通过:
  2. '在窗体放置4个控件:
  3. ' Command1:在属性窗口将 Index 属性设置为 0
  4. ' Check1: 在属性窗口将 Index 属性设置为 0,将 Style 属性设置为 1
  5. ' Picture1:不必设置任何属性
  6. ' Timer1: 不必设置任何属性
  7. ' 程序调试时要注意:终止程序要用运行中的 Form1 窗口关闭。不要使用 VB 主窗口的菜单命令或 VB 工具栏上的关闭按钮,这样无法关闭打开的视频窗口,导致 VB 无响应。如果 VB 无响应,只有用系统任务管理器才能终止 VB 进程,调试过程中所做的修改将丢失。
  8. '本人原创,转载请注明来源:http://hi.baidu.com/100bd/blog/item/525292c3a37f210d0ff47724.html
  9. Public ctCapWin As Long,ctRec As Boolean,ctDir As String,ctF As String,ctAutoSize As Boolean
  10. Dim ctRefresh As Boolean,ctConnect As Boolean,ctAutoHide As Boolean,IsFillScreen As Boolean
  11.  
  12. Private Declare Function GetCursorPos Lib "user32" (lpPoint As PointAPI) As Long
  13. Private Type PointAPI
  14. X As Long: Y As Long
  15. End Type
  16. Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long,ByVal hWndInsertAfter As Long,ByVal cX As Long,ByVal cY As Long,ByVal wFlags As Long) As Long
  17. Const HWND_Top = 0 'hWndInsertAfter 参数:Z序列的顶部
  18. Const HWND_TopMost = -1 '最前
  19. Const HWND_NoTopMost = -2 '不在最前
  20. Const HWND_Bottom = 1 '位于底层
  21. Const SWP_NoSize = &H1 'wFlags 参数
  22. Const SWP_NoMove = &H2
  23. Const SWP_NoZorder = &H4
  24. Const SWP_NoActivate = &H10
  25. Const SWP_ShowWindow = &H40
  26. Const SWP_HideWindow = &H80
  27.  
  28. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long,lParam As Any) As Long
  29. Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long,lParam As Long) As Long
  30. Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long,ByVal lParam As Long) As Long
  31. Const WM_Close = &H10
  32.  
  33. Private Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriver As Integer,ByVal lpszName As String,ByVal cbName As Long,ByVal lpszVer As String,ByVal cbVer As Long) As Boolean
  34. Private Declare Function capCreateCaptureWindow Lib "avicap32.dll" Alias "capCreateCaptureWindowW" (ByVal lpszWindowName As String,ByVal nID As Long) As Long
  35. Const WS_Child = &H40000000
  36. Const WS_Visible = &H10000000
  37. Const WS_Caption = &HC00000
  38. Const WS_ThickFrame = &H40000
  39.  
  40. Const GET_Frame = 1084
  41.  
  42. Const WM_User = &H400 '用户消息开始号,偏移地址:1024
  43. Const WM_CAP_GET_CAPSTREAMPTR = WM_User + 1 '
  44. Const WM_CAP_SET_CALLBACK_ERROR = WM_User + 2 '当出错回调函数
  45. Const WM_CAP_SET_CALLBACK_STATUS = WM_User + 3 '当状态(status)改变的时回调函数
  46. Const WM_CAP_SET_CALLBACK_YIELD = WM_User + 4 '在流捕获期间的回调函数
  47. Const WM_CAP_SET_CALLBACK_FRAME = WM_User + 5 '帧预览回调函数
  48. Const WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_User + 6 '在流捕获期间,当一个新的视频缓存区可用的时候就调用
  49. Const WM_CAP_SET_CALLBACK_WAVESTREAM = WM_User + 7 '在流捕获期间,当一个新的音频缓存区可用的时候就调用
  50.  
  51. Const WM_CAP_GET_USER_DATA = WM_User + 8 '获取:数据关联到一个捕捉窗口
  52. Const WM_CAP_SET_USER_DATA = WM_User + 9 '设置:数据关联到一个捕捉窗口
  53.  
  54. Const WM_CAP_DLG_VideoFormat = WM_User + 41 '对话框:视频格式
  55. Const WM_CAP_DLG_VideoSource = WM_User + 42 '对话框:视频源,枚举视频源,控制颜色、对比度、饱和度的改变。需视频驱动程序支技
  56. Const WM_CAP_DLG_VideoDisplay = WM_User + 43 '对话框:视频显示?控制视频捕捉过程中视频在显示器上的显示。对捕捉数据无影响,但会影响数了信号表达式
  57. Const WM_CAP_DLG_VideoCompression = WM_User + 46 '对话框:视频压缩
  58.  
  59. Private Enum enWinSet
  60. ' en_Copy = -1
  61. es_Show = 0
  62. es_Hide
  63. es_Close
  64. es_Move
  65. es_Size
  66. End Enum
  67.  
  68. '捕捉文件和缓存
  69. Const WM_Cap_File_Set_File = WM_User + 20 '设置当前的捕捉文件
  70. Const WM_Cap_File_Get_File = WM_User + 21 '得到当前的捕捉文件
  71. Const WM_CAP_FILE_ALLOCATE = WM_User + 22 '为捕捉文件预分配空间,从而可以减少被漏掉的帧
  72. Const WM_CAP_FILE_SaveAs = WM_User + 23 '将捕捉文件保存为另一个用户指定的文件。这个消息不会改变捕捉文件的名字和内容,'由于捕捉文件保留它最初的文件名,因此必须指定个新的文件文件名来保存
  73. Const WM_CAP_FILE_SET_INFOCHUNK = WM_User + 24 '可以把信息块例如文本或者自定义数据插入avi文件。同样用这个消息也可以清除avi文件中的信息块
  74. Const WM_CAP_FILE_SaveDIB = WM_User + 25 '把从帧缓存中复制出图像存为设备无关位图书馆(DIB),应用程序也可以使用这两个单帧捕捉消息来编辑帧序列,
  75. '或者创建一个慢速摄影序列
  76.  
  77. Const WM_CAP_Edit_Copy = WM_User + 30 '1054:把缓存中图像复制到剪贴板中
  78.  
  79. Const WM_CAP_SET_AUdioFORMAT = WM_User + 35 '设置音频格式。设置时传入一个WAVEFORMATWAVEFORMATEX、或PCMWAVEOFMAT结构的指针
  80. Const WM_CAP_GET_AUdioFORMAT = WM_User + 36 '来得到音频数据的格式和该格式结构体的大小。默认的捕捉音频格式是mono、8-bit和11kHZ PCM
  81.  
  82. Const WM_CAP_Get_VideoFormat = WM_User + 44 '给捕捉窗口来得到视频格式的结构和该结构的大小。
  83. Const WM_CAP_SET_VideoFormat = WM_User + 45 '用来设置视频格式
  84.  
  85. Const WM_CAP_SET_PreView = WM_User + 50 '发送给捕捉窗口来使预览模式有效或者失效
  86. Const WM_CAP_SET_Overlay = WM_User + 51 '使窗口处于叠加模式。使叠加模式有效也会自动地使预览模式失效
  87. Const WM_CAP_SET_PreViewRate = WM_User + 52 '发送给捕捉窗口来设置在预览模式下帧的显示频率
  88. Const WM_CAP_SET_Scale = WM_User + 53 '来使预览模式的缩放有效或者无效
  89.  
  90. Const WM_CAP_SET_SCROLL = WM_User + 55 '如果是在预览模式或者叠加模式,还可以通过本消息发送给窗口,
  91. '在窗口里的用户区域设置视频帧的滚动条的位置
  92. Private Type BitMapInfoHeader 'tagBitMapInfoHeader Structure
  93. biSize As Long '
  94. biWidth As Long
  95. biHeight As Long 'LONG DWORD
  96. biPlanes As Integer 'WORD
  97. biBitCount As Integer
  98. biCompression As Long
  99. biSizeImage As Long
  100. biXPelsPerMeter As Long
  101. biYPelsPerMeter As Long
  102. biClrUsed As Long
  103. biClrImportant As Long
  104. End Type
  105. Private Type BitMapInfo
  106. bmiHeader As BitMapInfoHeader '
  107. bmiColors As Byte 'RGBQUAD
  108. End Type
  109.  
  110.  
  111. '基本视频捕获消息--------------------------------------
  112. Const WM_CAP_Connect = WM_User + 10 '连接一个视频驱动,成功返回真(1)。连接驱动后,不一定就能显示视频,还要保证摄像头硬件连接良好、未被其他程序使用。
  113. Const WM_CAP_DisConnect = WM_User + 11 '断开视频窗口与驱动的连接
  114.  
  115.  
  116. ' wParam:视频设备序号,从 0 到 9
  117. Const WM_CAP_Sequence = WM_User + 62 '开始录像
  118. Const WM_CAP_Stop = WM_User + 68 '终止视频捕获
  119. Const WM_CAP_Abort = WM_User + 69 '暂停录像捕获?,成功返回真
  120. Const WM_CAP_Set_Sequence_Setup = WM_User + 64
  121. Const WM_CAP_Get_Sequence_Setup = WM_User + 65
  122.  
  123. '录像参数设置和获取
  124. 'Dim nParms As CaptureParms
  125. 'SendMessage ctCapWin,WM_CAP_Get_Sequence_Setup,Len(nParms),nParms'获取参数的设置
  126. 'nParms.fAbortLeftMouse = False '关闭:单击鼠标停止录像的功能
  127. 'SendMessage ctCapWin,WM_CAP_Set_Sequence_Setup,nParms'重新设置参数
  128. Private Type CaptureParms '
  129. dwRequestMicroSecPerFrame As Long 'DWORD
  130. fMakeUserHitOKToCapture As Boolean '开始录像时,是否显示确认对话框,默认为假
  131. wPercentDropForError As Long '每毫秒捕捉帧率,默认66667,即每秒15
  132. fYield As Boolean 'BOOL:如果为TRUE,将产生一个后台线程来进行视频捕捉
  133. dwIndexSize As Long 'DWORD:视频文件最大的索引入口数
  134. wChunkGranularity As Long 'UINT:以字节为单位表示AVI文件的大小
  135. fUsingDOSMemory As Boolean 'BOOL:未使用
  136. wNumVideoRequested As Long 'UINT:分配视频缓冲区的最大数量
  137. fCaptureAudio As Boolean '是否捕获音频流,默认值由具体的硬件设置
  138. wNumAudioRequested As Long '分配的音频缓冲区的最大数量
  139. vKeyAbort As Long '结束录像的按键,默认为 VK_ESCAPEEsc键)
  140. fAbortLeftMouse As Boolean '单击鼠标左键停止录像,默认为真
  141. fAbortRightMouse As Boolean '单击鼠标右键停止录像,默认为假
  142. fLimitEnabled As Boolean '是否开启捕获时间限制,默认为真
  143. wTimeLimit As Long '捕获时间限制(秒),fLimitEnabled 为真时有效
  144. fMCIControl As Boolean 'BOOL:为TRUE,控制MCI(媒体设备接口)兼容的视频源
  145. fStepMCIDevice As Boolean 'BOOL
  146. dwMCIStartTime As Long 'DWORD:以毫秒为单位标识MCI设备视频捕捉序列的起始位置,如果fMCIControl成员为FALSE,该成员被忽略
  147. dwMCIStopTime As Long 'DWORD:以毫秒为单位标识MCI设备视频捕捉序列的停止位置,如果fMCIControl成员为FALSE,该成员被忽略
  148. fStepCaptureAt2x As Boolean 'BOOL:为TRUE,捕捉的视频帧使用两个分辨率
  149. wStepCaptureAverageFrames As Long ':在捕捉时每帧图像使用的时间大小
  150. dwAudioBufferSize As Long '音频缓冲大小,默认0
  151. fDisableWriteCache As Boolean 'Win32系统未使用
  152. AVStreamMaster As Long '确定在写入AVI文件时,音频流是否控制时钟
  153. End Type
  154.  
  155. '视频窗口消息--------------------------------------
  156. 'Private Declare Function capGetDriverDescriptionA Lib "avicap32.dll" ( _
  157. 'ByVal wDriver As Integer,ByVal cbVer As Long) As Boolean
  158. '可利用此 API 获取所有驱动程序名称和版本信息。例子:
  159. ' Dim S As Long
  160. ' Dim lpszName As String * 128
  161. ' Dim lpszVer As String * 128
  162. '
  163. ' Do
  164. ' If Not capGetDriverDescriptionA(S,lpszName,128,lpszVer,128) Then Exit Do '获得驱动程序名称和版本信息
  165. ' S = S + 1
  166. ' Loop
  167. Const WM_CAP_Get_Status = WM_User + 54 '获取捕捉窗口的当前状态
  168. Private Type CapStatus '■■?
  169. uiImageWidth As Long '图像宽度,像素
  170. uiImageHeight As Long '图像高度,像素
  171. fLiveWindow As Boolean '视频显示是否使用预览
  172. fOverlayWindow As Boolean '视频显示是否使用硬件
  173. fScale As Boolean '图像是否随窗口大小自动缩放
  174. ptScroll As PointAPI 'POINT?
  175. fUsingDefaultPalette As Boolean '是否使用默认调色板
  176. fAudioHardware As Boolean '是否安装了音频波形硬件
  177. fCapFileExists As Boolean '是否生成了正确的捕获文件
  178. dwCurrentVideoFrame As Long
  179. dwCurrentVideoFramesDropped As Long
  180. dwCurrentWaveSamples As Long
  181. dwCurrentTimeElapsedMS As Long '视频流已录像时间(毫秒)
  182. hPalCurrent As Long 'HPALETTE 当前调色板句柄
  183. fCapturingNow As Boolean '是否正在进行捕获
  184. dwReturn As Long '错误返回值,根据这个数值可以调用一个错误回调函数
  185. wNumVideoAllocated As Long '视频缓冲
  186. wNumAudioAllocated As Long '音频缓冲
  187. End Type
  188.  
  189. Private Sub CloseMouse()
  190. Dim nParms As CaptureParms
  191. SendMessage ctCapWin,nParms '获取参数的设置
  192. 'nParms.fMakeUserHitOKToCapture = True '开始录像时,是否显示确认对话框
  193. nParms.fYield = True '用一个后台线程来进行视频捕捉
  194. nParms.fAbortLeftMouse = False '关闭:单击鼠标左键停止录像的功能
  195. nParms.fAbortRightMouse = False '关闭:单击鼠标右键停止录像的功能
  196. SendMessage ctCapWin,nParms '重新设置参数
  197. 'ff = SendMessageLong(ctCapWin,WM_CAP_SET_CALLBACK_STATUS,AddressOf CallBackStatus) '状态回调函数
  198. 'ff = SendMessageLong(ctCapWin,WM_CAP_SET_CALLBACK_FRAME,AddressOf MyFrameCallback) '帧回调函数
  199. 'ff = SendMessageLong(ctCapWin,WM_CAP_SET_CALLBACK_YIELD,AddressOf CallbackYield)
  200. End Sub
  201.  
  202. Private Sub NoRecord()
  203. SendMessage ctCapWin,WM_CAP_Stop,0 '停止录像
  204. ctRec = False: Call SetCaption(" ")
  205. End Sub
  206.  
  207. Private Sub StartRecord()
  208. Dim F As String,nDir As String,nF As String
  209.  
  210. '如果路径不存在,用默认文件名 C:\CAPTURE.AVI
  211. nDir = Trim(ctDir)
  212. If nDir = "" Or nDir = "<>" Or nDir = "<默认>" Then nDir = App.Path & "\videos"
  213. If Right(nDir,1) <> "" Then nDir = nDir & ""
  214. If Not MakePath(nDir) Then
  215. MsgBox "在指定的位置无法建立目录:" & vbCrLf & nPath,"保存视频文件"
  216. Exit Sub
  217. End If
  218. nF = Trim(ctF)
  219. If nF = "" Or nF = "<>" Or nF = "<默认>" Then nF = Format(Now,"yyyymmdd-hhmmss") & ".avi"
  220. If InStr(nF,".") = 0 Then nF = nF & ".avi"
  221. F = nDir & nF
  222. If CheckDirFile(F) = 1 Then
  223. If vbNo = MsgBox("文件已存在,覆盖此文件吗?" & vbCrLf & F,vbInformation + vbYesNo,"开始录像") Then Exit Sub
  224. On Error GoTo Cuo
  225. SetAttr F,0
  226. Kill F
  227. On Error GoTo 0
  228. End If
  229. ctRec = False
  230. SetWin ctCapWin,es_Size,1
  231. ctRec = True
  232. Call SetCaption("正在录像:" & nF)
  233. Call KjEnabled(True)
  234. DoEvents
  235. Call CloseMouse
  236. SendMessage ctCapWin,ByVal F '设置录像保存的文件
  237. PostMessage ctCapWin,0 '开始录像
  238. If ctAutoHide Then Me.Visible = False
  239. Exit Sub
  240. Cuo:
  241. MsgBox "无法写文件:" & vbvrlf & vbCrLf & F,"录像 - 错误"
  242. End Sub
  243. ' ' 一篇文章放不下全部代码,这是仅是第一页,转到:第二页'本人原创,转载请注明来源:http://hi.baidu.com/100bd/blog/item/525292c3a37f210d0ff47724.html
  244. 第二页
  245. ' ' 一篇文章放不下全部代码,这仅是第二页,转到:第一页
  246.   本程序是“实现USB摄像头视频图像的监控、截图、录像”的改进。可实现对摄像头视频的监控、截图、录像,可以分别保存为图片文件和视频(压缩)文件。保存的视频文件可以用媒体播放机(Windows Media Player)、 暴风影音等软件进行播放,轻松实现家庭录像制作。
  247. 【转】VB程序VB代码:摄像头视频图像的监控、截图、录像(改进)
  248. 【转】VB程序VB代码:摄像头视频图像的监控、截图、录像(改进)
  249. 【转】VB程序VB代码:摄像头视频图像的监控、截图、录像(改进)
  250.  
  251.  
  252. ' ' 一篇文章放不下全部代码,这仅是第二页,转到:第一页
  253. Private Sub SetDir()
  254. Dim nStr As String
  255. If Trim(ctDir) = "" Then ctDir = App.Path & "\videos" '如果路径不存在,用默认文件名 C:\CAPTURE.AVI
  256. nStr = "设置录像保存的文件夹。" & vbCrLf & "输入“<>”表示使用默认文件夹:" & vbCrLf & App.Path & "\videos"
  257. nStr = Trim(InputBox(nStr,"录像保存的文件夹",ctDir))
  258. If nStr = "" Then Exit Sub
  259. ctDir = nStr
  260. If ctDir = "<>" Or ctDir = "<默认>" Then ctDir = ""
  261. End Sub
  262.  
  263. Private Sub SetFile()
  264. Dim nStr As String,nF As String
  265. nF = String(255," ")
  266. SendMessage ctCapWin,WM_Cap_File_Get_File,Len(nF),ByVal nF
  267. nF = GetStrLeft(nF,vbNullChar)
  268. If Trim(ctF) = "" Then ctF = "<默认>" '如果路径不存在,用默认文件 C:\CAPTURE.AVI
  269. nStr = "设置录像保存的文件名(不带路径)。" & vbCrLf & "输入“<>”表示使用默认文件名:日期-时间.扩展名"
  270. nStr = Trim(InputBox(nStr,ctF))
  271. If nStr = "" Then Exit Sub
  272. ctF = nStr
  273. If ctF = "<>" Or ctF = "<默认>" Then ctF = ""
  274. SendMessage ctCapWin,ByVal ctF
  275. End Sub
  276.  
  277. Private Function GetStrLeft(nStr As String,Fu As String) As String
  278. '去掉 Fu 及后面的字符
  279. Dim S As Long
  280. S = InStr(nStr,Fu)
  281. If S > 0 Then GetStrLeft = Left(nStr,S - 1) Else GetStrLeft = nStr
  282. End Function
  283.  
  284. Private Function CheckDirFile(nDirFile) As Long
  285. '检查目录或文件夹,返回值:0不存在,1文件2是目录
  286. Dim nStr As String,nD As Boolean
  287. nStr = Dir(nDirFile,23)
  288. If nStr = "" Then Exit Function
  289. nD = GetAttr(nDirFile) And 16
  290. If nD Then CheckDirFile = 2 Else CheckDirFile = 1
  291. End Function
  292.  
  293. Private Sub Form_Load()
  294. Dim W As Long,H As Long
  295. Call SetCaption("")
  296. Me.ScaleMode = 3: Picture1.ScaleMode = 3
  297. Picture1.BorderStyle = 0
  298. Set Command1(0).Container = Picture1
  299. Set Check1(0).Container = Picture1
  300.  
  301. Call ReadSaveSet '读取用户设置
  302. '装载数组控件
  303. AddKj Command1,"连","Connect","连接摄像头"
  304. AddKj Command1,"断","DisConnect","断开与摄像头的连接"
  305. AddKj Command1,"-"
  306. AddKj Command1,"源","VideoSource","选择:视频源"
  307. AddKj Command1,"格","VideoFormat","设置:视频格式,分辨率"
  308. AddKj Command1,"显","VideoDisplay","视频显示对话框。某些显卡不支持功能。"
  309. AddKj Command1,"夹","SetDir","设置录像文件保存的文件夹。默认为主程序所在目录下的“videos”文件夹"
  310. AddKj Command1,"文","SetFile","录像保存的文件名,默认为:时间-编号.扩展名"
  311. AddKj Command1,"压","VideoCompression","设置:视频录像文件的压缩方式"
  312. AddKj Command1,"录","Record","开始录像"
  313. AddKj Command1,"停","NoRecord","停止录像"
  314. AddKj Command1,"图","CopyImg","将当前图像复制到剪贴板"
  315. AddKj Command1,"全","FillScreen","切换:全屏/窗口"
  316. AddKj Command1,"关","Exit","关闭退出程序"
  317. If ctAutoSize Then W = 1 Else W = 0
  318. AddKj(Check1,"自","AutoSize","视频窗口是否随主窗口自动改变大小").Value = W
  319. If ctAutoHide Then W = 1 Else W = 0
  320. AddKj(Check1,"隐","AutoHide","录像时自动隐藏主窗口").Value = W
  321. ' ctAutoSize = True '预览图像随窗口自动缩放
  322. ListKj Command1,Command1(0).Height * 0.1 '排列数组控件
  323. W = Command1.UBound: W = Command1(W).Left + Command1(W).Width * 2
  324. ListKj Check1,W '排列数组控件
  325. Picture1.Height = Command1(0).Height * 1.2
  326. Call WinCenter '窗口居中
  327. ctRefresh = True
  328. Call CreateCapWin '创建视频窗口
  329. Call KjEnabled(True)
  330. Timer1.Enabled = True: Timer1.Interval = 500
  331. End Sub
  332.  
  333. Private Sub Form_Resize()
  334. Picture1.Move 0,Me.ScaleWidth,Command1(0).Height * 1.3
  335. If ctAutoSize Then SetWin ctCapWin,es_Size '视频子窗口随主窗口自动改变大小
  336. End Sub
  337.  
  338. Private Sub Timer1_Timer()
  339. Dim nP As PointAPI,X As Long,Y As Long,H As Long
  340. Dim nStatus As CapStatus,nRec As Boolean
  341. ' '我读取窗口的当前状态 nStatus 总是失败,忘高手赐教
  342. ' X = SendMessageLong(ctCapWin,WM_CAP_Get_Status,Len(nStatus),ByVal VarPtr(nStatus))
  343. ' X = SendMessage(ctCapWin,nStatus)
  344. ' nRec = nStatus.fCapturingNow '是否正在进行捕获
  345. ' S = nStatus.uiImageWidth '图像宽度,像素
  346. ' Me.Caption = X
  347. GetCursorPos nP
  348. X = nP.X - Me.Left / Screen.TwipsPerPixelX
  349. Y = nP.Y - Me.Top / Screen.TwipsPerPixelY
  350. If Not IsFillScreen Then Exit Sub
  351. H = Me.Height / Screen.TwipsPerPixelY - Me.ScaleHeight '窗口标题栏高度
  352. If Y > -1 And Y < H + Picture1.Height Then
  353. If Picture1.Visible Then Exit Sub
  354. Picture1.Visible = True
  355. Else
  356. If Not Picture1.Visible Then Exit Sub
  357. Picture1.Visible = False
  358. End If
  359. SetWin ctCapWin,es_Size
  360. End Sub
  361.  
  362. Private Sub SetCaption(Optional nCap As String)
  363. If nCap <> "" Then Me.Tag = Trim(nCap)
  364. If IsFillScreen Then '全屏方式
  365. Me.Caption = ""
  366. Else '窗口方式
  367. If Me.Tag = "" Then Me.Caption = "摄像头控制" Else Me.Caption = "摄像头控制 - " & Me.Tag
  368. End If
  369. End Sub
  370.  
  371. Private Sub Check1_Click(Index As Integer)
  372. Dim nTag As String,TF As Boolean
  373. If Not ctRefresh Then Exit Sub
  374. nTag = Check1(Index).Tag: TF = Check1(Index).Value = 1
  375. Select Case LCase(nTag)
  376. Case LCase("AutoSize")
  377. ctAutoSize = TF
  378. SendMessage ctCapWin,WM_CAP_SET_Scale,ctAutoSize,0 '预览图像随窗口自动缩放
  379. Call SetWin(ctCapWin,es_Size)
  380. Case LCase("AutoHide")
  381. ctAutoHide = TF
  382. End Select
  383. End Sub
  384.  
  385. Private Sub Command1_Click(Index As Integer)
  386. Cmd Command1(Index).Tag
  387. End Sub
  388.  
  389. Private Sub Cmd(nCmd As String)
  390. Select Case LCase(nCmd)
  391. Case LCase("Connect"): Call CapConnect ' 连接摄像头
  392. Case LCase("DisConnect"): ctConnect = False: SendMessage ctCapWin,0 '断开摄像头连接
  393. Case LCase("VideoSource"): SendMessage ctCapWin,WM_CAP_DLG_VideoSource,0 '对话框:视频源
  394. Case LCase("VideoFormat"): SendMessage ctCapWin,WM_CAP_DLG_VideoFormat,0: Call SetWin(ctCapWin,es_Size) '显示对话框:视频格式,分辨率
  395. Case LCase("VideoDisplay"): SendMessage ctCapWin,WM_CAP_DLG_VideoDisplay,0 '对话框:视频显示。某些显卡不支持
  396. Case LCase("SetDir"): Call SetDir
  397. Case LCase("SetFile"): Call SetFile
  398. Case LCase("VideoCompression"): SendMessage ctCapWin,WM_CAP_DLG_VideoCompression,0 '对话框:视频压缩
  399. Case LCase("Record"): Call StartRecord
  400. Case LCase("NoRecord"): Call NoRecord
  401. Case LCase("CopyImg"): Clipboard.Clear: SendMessage ctCapWin,0 '将当前图像复制到剪贴板
  402. Case LCase("FillScreen"): Call FillScreen
  403. Case LCase("")
  404. Case LCase("")
  405. Case LCase("")
  406. Case LCase("Exit"): Unload Me: Exit Sub
  407. End Select
  408. Call KjEnabled(True)
  409. End Sub
  410.  
  411. Public Sub FillScreen()
  412. '全屏切换
  413. IsFillScreen = Not IsFillScreen
  414. Picture1.Visible = Not IsFillScreen
  415. If IsFillScreen Then Me.BorderStyle = 0 Else Me.BorderStyle = 2
  416. Call SetCaption
  417. If IsFillScreen Then '全屏方式
  418. Me.WindowState = 2
  419. Check1(KjIndex(Check1,"AutoSize")).Value = 1 '切换到:视频窗口随主窗口自动改变大小
  420. Else '窗口方式
  421. Me.WindowState = 0
  422. Call WinCenter '窗口居中
  423. End If
  424. Check1(KjIndex(Check1,"AutoSize")).Enabled = Not IsFillScreen
  425. End Sub
  426.  
  427. Private Sub WinCenter()
  428. '窗口居中
  429. Dim W As Long,H As Long
  430. W = 650 * Screen.TwipsPerPixelX: H = 560 * Screen.TwipsPerPixelY
  431. Me.Move (Screen.Width - W) * 0.5,(Screen.Height - H) * 0.5,W,H '窗口居中
  432. End Sub
  433.  
  434. Private Sub VideoSize(W As Long,H As Long)
  435. '获取视频的大小尺寸
  436. Dim nInf As BitMapInfo
  437. SendMessage ctCapWin,WM_CAP_Get_VideoFormat,Len(nInf),nInf
  438. W = nInf.bmiHeader.biWidth: H = nInf.bmiHeader.biHeight
  439. End Sub
  440.  
  441. Private Function AddKj(Kj As Object,nCap As String,Optional nTag As String,Optional nNote As String) As Control
  442. '装载一个数组控件
  443. Dim I As Long
  444. I = Kj.UBound
  445. If Kj(I).Tag <> "" Then I = I + 1: Load Kj(I)
  446. On Error Resume Next
  447. Kj(I).Caption = nCap
  448. If nTag = "" Then Kj(I).Tag = Kj(I).Name & "-" & I Else Kj(I).Tag = nTag
  449. Kj(I).ToolTipText = nNote
  450. Set AddKj = Kj(I)
  451. End Function
  452.  
  453. Private Sub ListKj(Kj As Object,L As Long)
  454. '排列数组控件
  455. Dim I As Long,H1 As Long,T As Long,W As Long
  456. H1 = Picture1.TextHeight("A"): T = H1 * 0.25: W = H1 * 2
  457. For I = Kj.lBound To Kj.UBound
  458. If Kj(I).Caption = "-" Then
  459. L = L + H1: Kj(I).Visible = False
  460. Else
  461. Kj(I).Move L,W: Kj(I).Visible = True
  462. L = L + W
  463. End If
  464. Next
  465. End Sub
  466.  
  467. Private Function KjIndex(Kj As Object,nTag As String) As Long
  468. Dim I As Long
  469. For I = Kj.lBound To Kj.UBound
  470. If LCase(Kj(I).Tag) = LCase(nTag) Then KjIndex = I: Exit Function
  471. Next
  472. KjIndex = -1
  473. End Function
  474.  
  475. Private Sub KjEnabled(Optional nEnabled As Boolean)
  476. Dim Kj,TF As Boolean,nType As String
  477. On Error Resume Next
  478. For Each Kj In Me.Controls
  479. nType = LCase(TypeName(Kj))
  480. If nType = "commandbutton" Or nType = "checkBox" Then
  481. Kj.Enabled = nEnabled
  482. End If
  483. Next
  484.  
  485. Command1(KjIndex(Command1,"FillScreen")).Enabled = True
  486. Command1(KjIndex(Command1,"Exit")).Enabled = True
  487. Check1(KjIndex(Check1,"AutoSize")).Enabled = Not IsFillScreen
  488. If Not nEnabled Then Exit Sub
  489. TF = ctConnect
  490. If ctRec Then TF = False
  491. Command1(KjIndex(Command1,"Connect")).Enabled = Not TF
  492. Command1(KjIndex(Command1,"DisConnect")).Enabled = TF '按钮在摄像头连接状态才可用
  493. Command1(KjIndex(Command1,"VideoSource")).Enabled = TF
  494. Command1(KjIndex(Command1,"VideoFormat")).Enabled = TF
  495. Command1(KjIndex(Command1,"VideoDisplay")).Enabled = TF
  496.  
  497. Command1(KjIndex(Command1,"VideoCompression")).Enabled = TF
  498. Command1(KjIndex(Command1,"Record")).Enabled = TF
  499. Command1(KjIndex(Command1,"NoRecord")).Enabled = TF
  500. Command1(KjIndex(Command1,"CopyImg")).Enabled = TF
  501. If Not ctRec Then Exit Sub
  502. Command1(KjIndex(Command1,"Record")).Enabled = False
  503. Command1(KjIndex(Command1,"NoRecord")).Enabled = True
  504. Command1(KjIndex(Command1,"SetFile")).Enabled = False
  505. Command1(KjIndex(Command1,"SetDir")).Enabled = False
  506. End Sub
  507.  
  508. Private Sub CreateCapWin()
  509. '创建视频窗口
  510. Dim nStyle As Long,S As Long
  511. Dim lpszName As String * 128
  512. Dim lpszVer As String * 128
  513. Do
  514. If Not capGetDriverDescriptionA(S,128) Then Exit Do '获得驱动程序名称和版本信息
  515. S = S + 1
  516. Loop
  517. nStyle = WS_Child + WS_Visible '+ WS_Caption + WS_ThickFrame '子窗口+可见+标题栏+边框
  518. If ctCapWin <> 0 Then Exit Sub
  519. ctCapWin = capCreateCaptureWindow("我创建的视频窗口",Me.hwnd,0)
  520. If ctCapWin = 0 Then Exit Sub
  521. SetWin ctCapWin,es_Move,Command1(0).Top + Command1(0).Height * 1.2,480
  522. End Sub
  523.  
  524. Private Sub CapConnect()
  525. Dim D As Long
  526. '打开摄像头
  527. D = SendMessage(ctCapWin,0) '连接一个视频驱动,成功返回真(1)
  528. SendMessage ctCapWin,0 '预览图像随窗口自动缩放
  529. SendMessage ctCapWin,WM_CAP_SET_PreViewRate,0 '设置预览显示频率
  530. SendMessage ctCapWin,WM_CAP_SET_PreView,0 '第三个参数:1-预览模式有效,0-预览模式无效
  531. ctConnect = True
  532. Call SetWin(ctCapWin,es_Size) '调整视频窗口为正确的大小
  533. End Sub
  534.  
  535. Private Sub SetWin(hWnds As Long,nSet As enWinSet,Optional ByVal L As Long,Optional ByVal T As Long,Optional ByVal W As Long,Optional ByVal H As Long)
  536. Dim hWndZOrder As Long,wFlags As Long
  537. If hWnds = 0 Then Exit Sub
  538. Select Case nSet
  539. Case es_Close: SendMessage hWnds,WM_Close,0: Exit Sub
  540. Case es_Hide: wFlags = SWP_NoMove + SWP_NoSize + SWP_NoZorder + SWP_HideWindow '隐藏
  541. Case es_Show: hWndZOrder = HWND_Top: wFlags = SWP_NoSize + SWP_ShowWindow '显示
  542. Case es_Move
  543. hWndZOrder = HWND_Top: wFlags = SWP_NoActivate + SWP_NoSize
  544. Case es_Size
  545. hWndZOrder = HWND_Top: wFlags = SWP_NoActivate
  546. '录像状态下改变视频窗口大小,有时会出现莫名其妙的错误
  547. If ctRec Then wFlags = wFlags + SWP_NoSize
  548. L = 0
  549. If Picture1.Visible Then T = Picture1.Height
  550. If ctAutoSize Then
  551. W = Me.ScaleWidth - L
  552. If H = 1 Then H = Me.ScaleHeight Else H = Me.ScaleHeight - T
  553. Else
  554. Call VideoSize(W,H) '获取视频的实际大小
  555. End If
  556. If W < 20 Or H < 20 Then Exit Sub
  557. End Select
  558. SetWindowPos hWnds,hWndZOrder,L,H,wFlags
  559. End Sub
  560.  
  561. Private Sub ReadSaveSet(Optional IsSave As Boolean)
  562. Dim nPath As String,nSub As String
  563. nPath = "摄像头控制": nSub = "UserSet"
  564. If IsSave Then
  565. SaveSetting nPath,ctAutoSize
  566. SaveSetting nPath,ctAutoHide
  567. SaveSetting nPath,"Path",ctDir
  568. SaveSetting nPath,"File",ctF
  569. Else
  570. ctAutoSize = GetSetting(nPath,"False")
  571. ctAutoHide = GetSetting(nPath,"False")
  572. ctDir = GetSetting(nPath,"")
  573. ctF = GetSetting(nPath,"")
  574. End If
  575. End Sub
  576.  
  577. Private Sub Form_Unload(Cancel As Integer)
  578. '停止摄像头。一般情况,如果母窗体关闭,子窗体就会自动释放。下面两句代码是否可省?
  579. If ctRec Then Call NoRecord
  580. Cmd "DisConnect" '断开摄像头连接
  581. SetWin ctCapWin,es_Close
  582. Call ReadSaveSet(True) '保存用户设置
  583. End Sub
  584.  
  585. Private Function CutPathFile(nStr As String,nFile As String)
  586. '分解出文件和目录
  587. Dim I As Long,S As Long
  588. For I = 1 To Len(nStr)
  589. If Mid(nStr,1) = "" Then S = I '查找最后一个目录分隔符
  590. Next
  591. If S > 0 Then
  592. nPath = Left(nStr,S + 1)
  593. Else
  594. nPath = "": nFile = nStr
  595. End If
  596. End Function
  597.  
  598. Private Function MakePath(ByVal nPath As String) As Boolean
  599. '逐级建立目录,成功返回 T
  600. Dim I As Long,IsPath As Boolean
  601. nPath = Trim(nPath)
  602. If Right(nPath,1) <> "" Then nPath = nPath & ""
  603. On Error GoTo Exit1
  604. For I = 1 To Len(nPath)
  605. If Mid(nPath,1) = "" Then
  606. Path1 = Left(nPath,I - 1)
  607. If Dir(Path1,23) = "" Then
  608. MkDir Path1
  609. Else
  610. IsPath = GetAttr(Path1) And 16
  611. If Not IsPath Then Exit Function '有一个同名的文件
  612. End If
  613. End If
  614. Next
  615. MakePath = True: Exit Function
  616. Exit1:
  617. End Function

猜你在找的VB相关文章