Browse Source

【软件版本】
V
【模块名称】

【问题原因】
摄像头拨插时,问题仍有,新增刷新按钮处理。
【修改描述】

【测试结果】

sat23 3 years ago
parent
commit
4f2fde4367

+ 2 - 2
FieldTestTool/FieldTestTool/CaptureVideo.cpp

@@ -46,7 +46,7 @@ int CCaptureVideo::EnumDevices(CMFCRibbonComboBox *pCombobox)
 	HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
 	if (hr != NOERROR)
     {
-        CoUninitialize();
+        //CoUninitialize();
         return -1;
     }
 
@@ -55,7 +55,7 @@ int CCaptureVideo::EnumDevices(CMFCRibbonComboBox *pCombobox)
 	hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum, 0);
 	if (hr != NOERROR)
     {
-        CoUninitialize();
+        //CoUninitialize();
         return -1;
     }
 

+ 1 - 0
FieldTestTool/FieldTestTool/FieldTestTool.rc

@@ -395,6 +395,7 @@ BEGIN
     IDS_RIBBON_SWITCHER_CHECKBOX "Open"
     IDS_RIBBON_SWITCHER_CHECKBOXA "SwitchA"
     IDS_RIBBON_SWITCHER_CHECKBOXB "SwitchB"
+    IDS_RIBBON_CAMERA_FLUSH "Flush"
 END
 
 STRINGTABLE 

+ 5 - 1
FieldTestTool/FieldTestTool/FieldTestTool.vcproj

@@ -102,7 +102,7 @@
 			IntermediateDirectory="$(OutDir)$(ConfigurationName)"
 			ConfigurationType="1"
 			UseOfMFC="2"
-			CharacterSet="1"
+			CharacterSet="2"
 			WholeProgramOptimization="1"
 			>
 			<Tool
@@ -479,5 +479,9 @@
 		</File>
 	</Files>
 	<Globals>
+		<Global
+			Name="RESOURCE_FILE"
+			Value="FieldTestTool.rc"
+		/>
 	</Globals>
 </VisualStudioProject>

+ 106 - 16
FieldTestTool/FieldTestTool/MainFrm.cpp

@@ -47,6 +47,9 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
     // 摄像头;
     ON_COMMAND(ID_RIBBON_CAMERA_COMBOBOX, &CMainFrame::OnCameraCombobox)
     ON_UPDATE_COMMAND_UI(ID_RIBBON_CAMERA_COMBOBOX, &CMainFrame::OnUpdateCameraCombobox)
+    // 摄像头刷新;
+    ON_COMMAND(ID_RIBBON_CAMERA_FLUSH, &CMainFrame::OnCameraFlush)
+    ON_UPDATE_COMMAND_UI(ID_RIBBON_CAMERA_FLUSH, &CMainFrame::OnUpdateCameraFlush)
     // 红外:测试精灵;
     ON_COMMAND(ID_RIBBON_INFRAED_COMBOBOX, &CMainFrame::OnInfraedCombobox)
     ON_UPDATE_COMMAND_UI(ID_RIBBON_INFRAED_COMBOBOX, &CMainFrame::OnUpdateInfraedCombobox)
@@ -292,8 +295,14 @@ void CMainFrame::InitializeRibbon()
 
         CMFCRibbonComboBox *pCameraCombobx = new CMFCRibbonComboBox(ID_RIBBON_CAMERA_COMBOBOX, FALSE);
         pGroup->AddButton(pCameraCombobx);
-        pCameraCombobx->SetWidth(120);
+        pCameraCombobx->SetWidth(80);
         pCameraCombobx->SetCompactMode(FALSE);
+
+        bNameValid = strTemp.LoadString(IDS_RIBBON_CAMERA_FLUSH);
+        ASSERT(bNameValid);
+        CMFCRibbonButton *pCameraFlush = new CMFCRibbonButton(ID_RIBBON_CAMERA_FLUSH, strTemp);
+        pGroup->AddButton(pCameraFlush);
+        pGroup->SetCompactMode(FALSE);
     }
     
     //////////////////////////////////////////////////////////////////////////
@@ -386,7 +395,6 @@ void CMainFrame::InitializeRibbon()
 #endif
 
 	m_wndRibbonBar.AddToTabs(new CMFCRibbonButton(ID_APP_ABOUT, _T("\na"), m_PanelImages.ExtractIcon (0)));
-
 }
 
 BOOL CMainFrame::CreateDockingWindows()
@@ -660,7 +668,6 @@ void CMainFrame::OnCameraCombobox()
                     pView->m_pCamera = new CCaptureVideo();
                 pView->m_pCamera->Init(nCurSel, m_pChildFrame->GetSafeHwnd());
             }
-            
         }
     }
 }
@@ -838,6 +845,56 @@ void CMainFrame::OnUpdateSwitcherCheckboxB(CCmdUI* pCmdUI)
     pCmdUI->SetCheck(m_bSwitcherCheckB);
 }
 
+void CMainFrame::OnCameraFlush()
+{
+    CMFCRibbonBar* pRibbon = GetRibbonBar();
+    ASSERT_VALID(pRibbon);
+    CMFCRibbonComboBox* pCameraCombo = DYNAMIC_DOWNCAST(CMFCRibbonComboBox, pRibbon->FindByID(ID_RIBBON_CAMERA_COMBOBOX));
+    std::vector<TString> vtDevices;
+    EnumDevices(vtDevices);
+    int nCurSel = pCameraCombo->GetCurSel();
+    if ( nCurSel != -1 )
+    {    
+        bool bDel = true;
+        TString str = pCameraCombo->GetItem(pCameraCombo->GetCurSel());
+        for ( std::vector<TString>::iterator it = vtDevices.begin(); it != vtDevices.end(); it++ )
+        {
+            if ( _tcscmp(str.c_str(), it->c_str()) == 0 )
+            {
+                bDel = false;
+                break;
+            }
+        }
+
+        if ( bDel && m_pChildFrame )
+        {
+            CFieldTestToolView *pView = (CFieldTestToolView*)m_pChildFrame->GetActiveView();
+            if ( pView->m_pCamera )
+                delete pView->m_pCamera;
+            pView->m_pCamera = NULL;
+            pView->CloseWindow();
+            pView->DestroyWindow();
+
+            m_pChildFrame->CloseWindow();
+            m_pChildFrame = NULL;
+
+            // 设备移除后,设置空;
+            pCameraCombo->DeleteItem(nCurSel);
+        }
+    }
+
+    pCameraCombo->RemoveAllItems();
+    for (std::vector<TString>::iterator it = vtDevices.begin(); it != vtDevices.end(); it++)
+    {
+        pCameraCombo->AddItem(it->c_str());
+    }
+}
+
+void CMainFrame::OnUpdateCameraFlush(CCmdUI* pCmdUI)
+{
+    //pCmdUI->Enable();
+}
+
 bool CMainFrame::RegisterDeviceChange()
 {
     // HID设备的GUID,可在设备管理器中查询,经查结果如下:
@@ -880,7 +937,7 @@ bool CMainFrame::RegisterDeviceChange()
     return true;
 #endif    
 }
-#include <string>
+
 BOOL CMainFrame::OnDeviceChange(UINT nEventType, DWORD_PTR dwData)
 {
     if ( dwData == 0 )
@@ -981,22 +1038,55 @@ BOOL CMainFrame::OnDeviceChange(UINT nEventType, DWORD_PTR dwData)
     // USB等接口设备;
     if ( pdbd->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE )
     {
-#if 0
         DEV_BROADCAST_HDR* phdr = (DEV_BROADCAST_HDR*)dwData;
         CMFCRibbonComboBox* pCameraCombo = DYNAMIC_DOWNCAST(CMFCRibbonComboBox, pRibbon->FindByID(ID_RIBBON_CAMERA_COMBOBOX));
-        // 加了线程锁也报错;
-        AutoThreadSection at(&g_csCamera);
-        m_cap.EnumDevices(pCameraCombo);
-#else
-        if ( nEventType == DBT_DEVICEREMOVECOMPLETE )
-        {// 设备拨掉;
-          
-        }
-        else if ( nEventType == DBT_DEVICEARRIVAL )
-        {// 设备插入;
+        std::vector<TString> vtDevices;
+        if ( nEventType == DBT_DEVICEREMOVECOMPLETE || nEventType == DBT_DEVICEARRIVAL)
+        {
+            OutputDebugString(_T("设备有变化===============\n"));
+            // 新增时,需要等待系统刷新后才能遍历设备(有时仍不灵,添加刷新按钮处理);
+            if ( nEventType == DBT_DEVICEARRIVAL)
+                Sleep(1000);
+
+            EnumDevices(vtDevices);
+            int nCurSel = pCameraCombo->GetCurSel();
+            if ( nCurSel != -1 )
+            {    
+                bool bDel = true;
+                TString str = pCameraCombo->GetItem(pCameraCombo->GetCurSel());
+                for ( std::vector<TString>::iterator it = vtDevices.begin(); it != vtDevices.end(); it++ )
+                {
+                    if ( _tcscmp(str.c_str(), it->c_str()) == 0 )
+                    {
+                        bDel = false;
+                        break;
+                    }
+                }
 
+                if ( bDel && m_pChildFrame )
+                {
+                    CFieldTestToolView *pView = (CFieldTestToolView*)m_pChildFrame->GetActiveView();
+                    if ( pView->m_pCamera )
+                        delete pView->m_pCamera;
+                    pView->m_pCamera = NULL;
+                    pView->CloseWindow();
+                    pView->DestroyWindow();
+
+                    m_pChildFrame->CloseWindow();
+                    m_pChildFrame = NULL;
+
+                    // 设备移除后,设置空;
+                    pCameraCombo->DeleteItem(nCurSel);
+                    //pCameraCombo->SelectItem(-1);
+                }
+            }
+
+            pCameraCombo->RemoveAllItems();
+            for (std::vector<TString>::iterator it = vtDevices.begin(); it != vtDevices.end(); it++)
+            {
+                pCameraCombo->AddItem(it->c_str());
+            }
         }
-#endif
     }
 
     TRACE(_T("OnDeviceChange\n"));

+ 3 - 0
FieldTestTool/FieldTestTool/MainFrm.h

@@ -97,6 +97,9 @@ protected:
     afx_msg void OnUpdateSwitcherCheckboxA(CCmdUI* pCmdUI);
     afx_msg void OnSwitcherCheckboxB();
     afx_msg void OnUpdateSwitcherCheckboxB(CCmdUI* pCmdUI);
+    // 摄像头刷新按钮;
+    afx_msg void OnCameraFlush();
+    afx_msg void OnUpdateCameraFlush(CCmdUI* pCmdUI);
 
     // 注册设备变化监听;
     bool RegisterDeviceChange();

+ 10 - 0
FieldTestTool/FieldTestTool/PropertiesWnd.cpp

@@ -75,6 +75,7 @@ BEGIN_MESSAGE_MAP(CPropertiesWnd, CDockablePane)
     ON_UPDATE_COMMAND_UI_RANGE(BTNID, BTNID + 100, OnUpdateSignalBtnClick)
     // 下拉框事件;
     ON_CBN_SELCHANGE(1, &CPropertiesWnd::OnCbnSelchangeSingals)
+    ON_WM_DESTROY()
 END_MESSAGE_MAP()
 
 /////////////////////////////////////////////////////////////////////////////
@@ -642,3 +643,12 @@ void CPropertiesWnd::OnPaint()
     brush.CreateSolidBrush(((CMFCVisualManagerOffice2007*)CMFCVisualManagerOffice2007::GetInstance())->GetRibbonEditBackgroundColor(FALSE,FALSE));
     dc.FillRect(&rc, &brush);
 }
+
+
+void CPropertiesWnd::OnDestroy()
+{
+    CDockablePane::OnDestroy();
+
+    // TODO: 在此处添加消息处理程序代码
+    ClearAllBTNInfo();
+}

+ 1 - 0
FieldTestTool/FieldTestTool/PropertiesWnd.h

@@ -131,5 +131,6 @@ protected:
     void AutoSetDroppedWidth(CComboBox* pCombobox);
 public:
     afx_msg void OnPaint();
+    afx_msg void OnDestroy();
 };
 

+ 5 - 3
FieldTestTool/FieldTestTool/Resource.h

@@ -15,6 +15,7 @@
 #define IDS_STRING109                   109
 #define IDS_RIBBON_SWITCHER_CHECKBOXB   109
 #define IDB_WRITESMALL                  110
+#define IDS_RIBBON_CAMERA_FLUSH         110
 #define IDB_WRITELARGE                  111
 #define IDB_MAIN                        112
 #define IDB_BUTTONS                     113
@@ -102,14 +103,15 @@
 #define ID_RIBBON_SWITCHER_CHECKBOX     317
 #define ID_RIBBON_SWITCHER_CHECKBOXA    318
 #define ID_RIBBON_SWITCHER_CHECKBOXB    319
-#define ID_WRITE_PASTEASHYPERLINK       32770
+#define ID_RIBBON_CAMERA_FLUSH          320
+#define ID_WRITE_PASTEASHYPERLINK       32771
 
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        320
-#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_RESOURCE_VALUE        321
+#define _APS_NEXT_COMMAND_VALUE         32772
 #define _APS_NEXT_CONTROL_VALUE         1000
 #define _APS_NEXT_SYMED_VALUE           310
 #endif

+ 56 - 0
FieldTestTool/FieldTestTool/stdafx.cpp

@@ -16,3 +16,59 @@
 #include "stdafx.h"
 
 
+int EnumDevices(std::vector<TString> &vtDevices)
+{
+    ICreateDevEnum *pDevEnum = NULL;
+    IEnumMoniker *pEnum = NULL;
+    HRESULT hr = NULL;
+    CoInitialize(NULL);
+    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&pDevEnum));
+    if (SUCCEEDED(hr))
+    {
+        hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum,0);
+        if (hr == S_OK)
+        {
+            //枚举捕获设备
+            IMoniker *pMoniker = NULL;
+            ULONG cFetched;
+            while (pEnum->Next(1, &pMoniker, &cFetched) == S_OK)
+            {
+                IPropertyBag* pPropBag;
+                hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,reinterpret_cast<void**>(&pPropBag));
+                if (SUCCEEDED(hr))
+                {
+                    //获取 vid 和 pid
+                    BSTR devicePath = NULL;
+                    hr = pMoniker->GetDisplayName(NULL, NULL, &devicePath);
+                    if (!SUCCEEDED(hr))
+                    {
+                        pMoniker->Release();
+                        continue;
+                    }
+                    wchar_t* lpszDevicePath = _bstr_t(devicePath);
+
+                    //获取设备名称
+                    VARIANT varName;
+                    varName.vt = VT_BSTR;
+                    VariantInit(&varName);
+                    hr = pPropBag->Read(L"FriendlyName", &varName, 0);
+                    if (SUCCEEDED(hr))
+                    {
+                        TCHAR str[2048];
+                        WideCharToMultiByte(CP_ACP,0,varName.bstrVal, -1, str, 2048, NULL, NULL);
+                        OutputDebugString(_T("新增设备:"));
+                        OutputDebugString(str);
+                        OutputDebugString(_T("\n"));
+                        vtDevices.push_back(str);
+                        SysFreeString(varName.bstrVal);
+                    }
+                    pPropBag->Release();
+                }
+                pMoniker->Release();
+            }
+        }
+    }
+    CoUninitialize();
+
+    return 0;
+}

+ 1 - 0
FieldTestTool/FieldTestTool/stdafx.h

@@ -72,6 +72,7 @@
 #define DISABLE_OUTLOOKBAR
 
 
+extern int EnumDevices(std::vector<TString> &vtDevices);
 
 #ifdef _UNICODE
 #if defined _M_IX86