1. 程式人生 > >海康威視視訊ocx控制元件開發總結

海康威視視訊ocx控制元件開發總結

因工作需要,需要開發一個海康威視的視訊ocx控制元件,嵌入到intouch,組態王一類的組態軟體中使用。

之前從沒做過ocx控制元件的開發,連MFC的開發也沒做過,折騰了幾天,終於基本完成。記錄一下這個過程。

第一部分 ocx控制元件的建立

首先在網上查找了一下資料,按照下面這篇文章,建立了一個ocx控制元件。

http://blog.csdn.net/longhuahaha/article/details/8556964

為了防止自己忘了這個過程,現把這個文章完整的貼過來

1.ActiveX的基本概念

         ActiveX控制元件可以看作是一個極小的伺服器應用程式,它不能獨立執行,必須嵌入到某個容器程式中,與該容器一起執行。這個容器包括WEB網頁,應用程式窗體等。。。

         ActiveX控制元件的字尾名是OCX或者DLL。一般是以OCX和動態庫共存的形式打包成cab或者exe的檔案放在伺服器上,客戶端下載後執行安裝cab或exe解壓成OCX和動態庫共存的檔案,然後註冊ocx檔案。

         ActiveX控制元件是基於com標準,使得軟體部件在網路環境中進行互動的技術集。它與具體的程式語言無關。作為針對Internet應用開發的技術,ActiveX被廣泛應用於WEB伺服器以及客戶端的各個方面。同時,ActiveX技術也被用於方便地建立普通的桌面應用程式,此外ActiveX一般具有介面。

2.三個概念:ActiveX、OLE和COM

        從時間的角度講,OLE是最早出現的,然後是COM和 ActiveX;從體系結構角度講,OLE和ActiveX是建立在COM之上的,所以COM是基礎;單從名稱角度講,OLE、ActiveX是兩個商標名稱,而COM則是一個純技術名詞,這也是大家更多的聽說ActiveX和OLE的原因。COM是應OLE的需求而誕生的,所以雖然COM是OLE的基礎,但OLE的產生卻在COM之前。COM的基本出發點是,讓某個軟體通過一個通用的機構為另一個軟體提供服務。ActiveX最核心的技術還是COM。ActiveX和OLE的最大不同在於,OLE針對的是桌面上應用軟體和檔案之間的整合,而 ActiveX則以提供進一步的網路應用與使用者互動為主。COM物件可以用C++、

Java和VB等任意一種語言編寫,並可以用DLL或作為不同過程工作的執行檔案的形式來實現。使用COM物件的瀏覽器,無需關心物件是用什麼語言寫的,也無須關心它是以DLL還是以另外的過程來執行的。從瀏覽器端看,無任何區別。這樣一個通用的處理技巧非常有用。

3.ActiveX控制元件工程的建立

       使用VS2010有兩種方式可以建立ActiveX工程,

第一種:建立“MFC ActiveX 控制元件”工程;

第二種:建立“ATL 專案”。由於使用ATL開發ActiveX控制元件需要了解com技術,對程式設計師的要求也較高,開發時間也較長,所以如果ActiveX只在windows作業系統下執行,那麼就使用“MFC ActiveX 控制元件”工程來快速建立ActiveX控制元件。但是這裡要注意了:使用“MFC ActiveX 控制元件”工程來快速建立ActiveX控制元件,他不僅要建立在windows作業系統下,還必須在windows作業系統下安裝c++依賴庫安裝包,因為MFC是建立在微軟的c++動態庫的基礎上的。所以這兩種方式各有優缺點,根據專案需求來選擇適合的方式。

4.使用VS2010建立MFC ActiveX工程專案步驟

         由於使用ATL進行ActiveX工程的建立難度比較大,所以這裡先使用“MFC ActiveX 控制元件”工程來建立一個簡單的ActiveX控制元件。

       第一:新建專案-》選擇“MFC ActiveX 控制元件”工程,給專案命名TestMfcAtlDebug,點選確定,彈出“控制元件嚮導”對話方塊

        第二:在概述,應用程式設定,控制元件名稱和控制元件設定都可以選擇預設,然後點選“完成”,這樣“MFC ActiveX 控制元件”工程建立完成

5.分析“MFC ActiveX 控制元件”工程的三個重要的類以及對外介面定義檔案idl

使用嚮導建立完工程可以看到自動生成了三個類,TestMfcAtlDebug,TestMfcAtlDebugCtrl和TestMfcAtlDebugPropPage

可以開啟上面三個類的標頭檔案及cpp檔案,發現它們都是派生類。

TestMfcAtlDebug:cpp檔案中定義了DllRegisterServer和DllUnregisterServer,可以發現ActiveX的註冊和反組冊都與該類有關。

TestMfcAtlDebugCtrl:可以發現該標頭檔案中聲明瞭訊息對映(讓ActiveX控制元件程式可以接受系統傳送的事件通知,如窗體建立和關閉事件),排程對映(讓外部呼叫程式(包含ActiveX的容器)可以方便地訪問ActiveX控制元件的屬性和方法),事件對映(讓ActiveX控制元件可以向外部呼叫程式(包含ActiveX的容器)傳送事件通知)。也就是說對ActiveX控制元件的視窗操作都將在這個類中完成,包括ActiveX控制元件的建立,重繪,以及在此類中建立可視MFC窗體。

TestMfcAtlDebugPropPage:顯示ActiveX控制元件的屬性頁的

讓我們來看看最重要的部分:對外介面定義檔案TestMfcAtlDebug.idl,程式碼如下:

[cpp] view plain copy  print?
  1. #include <olectl.h>
  2. #include <idispids.h>
  3. uuid(69EE37F4-8B36-495F-9F60-5E3AAF2FB494), version(1.0),  
  4.   control ]  
  5. library TestMfcAtlDebugLib  
  6. {  
  7.     importlib(STDOLE_TLB);  
  8.     //  CTestMfcAtlDebugCtrl 的主排程介面
  9.     [   
  10.         uuid(6B60346D-5CCD-4907-83F4-51938558A9B7)    
  11.     ]  
  12.     dispinterface _DTestMfcAtlDebug  
  13.     {  
  14.         properties:  
  15.         methods:  
  16.             [id(DISPID_ABOUTBOX)] void AboutBox();  
  17.     };  
  18.     //  CTestMfcAtlDebugCtrl 的事件排程介面
  19.     [   
  20.         uuid(E26ECC46-9BA2-4C25-A4DD-A690560A5113)    
  21.     ]  
  22.     dispinterface _DTestMfcAtlDebugEvents  
  23.     {  
  24.         properties:  
  25.             //  事件介面沒有任何屬性
  26.         methods:  
  27.     };  
  28.     //  CTestMfcAtlDebugCtrl 的類資訊
  29.     [  
  30.         uuid(DD0CF7EF-A181-428C-B5FC-C44A1C13CA43)  
  31.     ]  
  32.     coclass TestMfcAtlDebug  
  33.     {  
  34.         [default] dispinterface _DTestMfcAtlDebug;  
  35.         [default, source] dispinterface _DTestMfcAtlDebugEvents;  
  36.     };  
  37. };  

這個就是對外介面定義檔案,如果外部程式想要呼叫ActiveX的方法,屬性以及在登錄檔註冊的classid(WEB網頁呼叫需要使用),就必須瞭解這個檔案,這個檔案可以分為四個部分來看:

首先是TestMfcAtlDebug.Lib這個庫資訊

這個就不做詳解

第二部分是排程對映的介面資訊,該介面資訊包含了屬性(如控制元件背景色)和對外方法

裡面定義了一個方法AboutBox(),該方法就可以被外部程式呼叫,在該接口裡定義的函式都是純虛擬函式,這些函式的實現都是在TestMfcAtlDebugCtrl中完成的,MFC通過底層的封裝,讓TestMfcAtlDebugCtrl類繼承這個介面,實現函式。

第三部分是事件對映的介面資訊

第四部分是類的資訊,其中uuid就是ActiveX控制元件註冊到登錄檔的classid,它是ActiveX註冊後在系統內的唯一標識,WEB網頁就是使用這個ID載入ActiveX控制元件的

6.定義排程對映和事件對映方法,提供給外部呼叫者使用
那麼怎麼定義新的排程對映和事件對映方法呢,如果手動定義很不方便,當然使用編譯器進行定義,步驟是開啟類檢視:

可以看到TestMfcAtlDebugLib中有_DTestMfcAtlDebug和_DTestMfcAtlDebugEvents,在_DTestMfcAtlDebug項中可以右鍵-》新增方法(或屬性),該操作是完成排程對映的方法和屬性的新增;在_DTestMfcAtlDebugEvents項中可以右鍵-》新增方法(或屬性),該操作是完成事件對映的方法和屬性的新增。

舉個例子,如果要新增一個排程對映的方法Fuck2(),使得外部可以呼叫:

在_DTestMfcAtlDebug項中可以右鍵-》新增方法,設定框

填寫完資訊後點擊完成,外部就可以呼叫方法Fuck2,同時ActiveX控制元件專案程式碼的內部將會在三個檔案中新增程式碼:

1.在

2.在

3.在

7.註冊ActiveX控制元件

按照上面的步驟已經完成簡單ActiveX控制元件(無窗體介面的控制元件)的編寫,重新生成後會在Debug下生成一個TestMfcAtlDebug.ocx的檔案,使用windows的dos視窗可以註冊這個ActiveX控制元件

步驟:

首先win+R鍵開啟執行,然後輸入註冊命令:regsvr32  c:\.......\TestMfcAtlDebug.ocx(反註冊命令:regsvr32  c:\.......\TestMfcAtlDebug.ocx -u)

有兩種情況會導致控制元件註冊失敗:

第一種:使用非Administrator使用者登入系統會由於許可權不足而無法註冊com元件,這時候就必須使用Administrator使用者登入作業系統

第二種:ActiveX控制元件所依賴的dll庫被程式給佔用,就會導致註冊失敗,解決辦法是將正在執行的程式關閉就可以 

 8.測試ActiveX控制元件的方法

按照上面的步驟已經完成ActiveX控制元件的編寫,也將這個控制元件註冊成功了,那麼怎麼測試這個控制元件呢,有三種方式:

第一種:使用html網頁來測試

在TestMfcActiveX.htm的檔案中編寫程式碼如下:

[html] view plain copy  print?
  1. <HTML>
  2. <HEAD>
  3. <TITLE>Test ActiveX</TITLE>
  4. </HEAD>
  5. <OBJECTID="TestMfcAtl Control"WIDTH=528HEIGHT=545classid="CLSID:DD0CF7EF-A181-428C-B5FC-C44A1C13CA43">
  6.     <PARAMNAME="_Version"VALUE="65536">
  7.     <PARAMNAME="_ExtentX"VALUE="12806">
  8.     <PARAMNAME="_ExtentY"VALUE="1747">
  9.     <PARAMNAME="_StockProps"VALUE="0">
  10. </OBJECT>
  11. </HTML>

注意上面的classid就是在idl檔案中類的uuid,然後開啟這個網頁就會顯示ActiveX控制元件。上面的classid在控制元件成功註冊後也可以通過登錄檔查詢,具體方法是win+R鍵,輸入regedit命令,就會彈出“登錄檔編輯器”,位置在“HKET_CLASSES_ROOT”中,根據你控制元件的名稱,快速按下前三個字母,然後就可以定位到比較好找的位置,如下圖

第二種:建立Mfc應用程式,在Mfc視窗右鍵-》插入“ActiveX”控制元件,然後就會在MFC的窗體上顯示ActiveX控制元件

第三種:也是最方便的一種方法,就是使用vs自帶的ActiveX Control Test Container來測試ActiveX控制元件,但是VS2010在“工具”中沒有這一項,那麼我們首先可以手動把這個工具新增到VS2010裡,首先找到C:\Program Files\Microsoft Visual Studio 10.0\Samples\2052\C++\MFC\ole\TstCon\TstCon.sln,然後使用VS2010開啟解決方案TstCon.sln,編譯專案TCProps和TstCon,編譯完成後會在C:\Program Files\Microsoft Visual Studio 10.0\Samples\2052\C++\MFC\ole\TstCon\Debug\中生成TstCon.exe執行程式,這個執行程式就是ActiveX Control Test Container,接下來我們就在VS2010中的工具中新增這個TstCon.exe,在VS2010中的“工具”選單項中選擇“外部工具”,在彈出的窗體中新增一個新的工具,標題為ActiveX Control Test Container,命令為C:\Program Files\Microsoft Visual Studio 10.0\Samples\2052\C++\MFC\ole\TstCon\Debug\TstCon.exe,然後點選確定就可以完成工具的添加了。

 

 這樣,在“工具”中就有了一個ActiveX Control Test Container,點選它就會彈出測試ActiveX的容器,如下圖

點選Edit->Insert New Control->選擇TestMfcAtlDebug Control,點選OK

然後就會顯示這個註冊後的AcitveX控制元件,如果要測試這個控制元件的排程對映的方法Fuck2,就先選中控制元件,然後點選Control-》Invoke Methods,在Methods Name下拉框中選擇Fuck2這個方法,點選Invoke按鈕就可以測試這個方法了,如下圖:

我們可以看到上面的ActiveX控制元件是一個空白的背景和一個圈組成的,並沒有窗體介面,那麼怎麼新增窗體呢?

9.向ActiveX控制元件中新增一個Mfc窗體,就是一個帶介面的ActiveX控制元件

 步驟:

第一:在資源檢視中新建一個對話方塊資源

去掉上邊的“確定”和“取消”按鈕,然後修改對話方塊屬性:Border改為None,Control改為Ture,ID改為IDD_MAIN_DIALOG,Style改為Child,System改為False,Visible改為True,然後在對話方塊中雙擊,為對話方塊新增一個類,如下圖:

 

點選“完成”。在解決方案資源管理器中新增了一個ViewDialog.h和ViewDialog.cpp這個ViewDialog類就是剛剛我們建立的對話方塊類

然後拖一個Edit Control到對話方塊上,修改其ID為IDC_EDIT_OUTPUT,再拖一個Button到對話方塊上,此時對話方塊效果為:

 對話方塊建立完成,接下來就是要把它新增到ActiveX控制元件中去

第二:在TestMfcAtlDebugCtrl.h中定義對話方塊例項m_VideoDlg

 然後在TestMfcAtlDebugCtrl類中定義兩個訊息對映:窗體建立完成訊息對映和窗體改變大小訊息對映

在VS2010的選單項“專案”--》“類嚮導”中,選擇要新增到的專案和類中,選擇“訊息”選項卡,選擇WM_CREATE後點擊”新增處理程式“按鈕和選擇WM_SIZE

後點擊”新增處理程式“,這樣在“現有的處理程式”中就有OnCreate和OnSize這兩個函式,點選確定,完成訊息對映函式的新增,如圖:

 在TestMfcAtlDebugCtrl.cpp中自動新增下列程式碼,如圖:

 在OnCreate函式中編寫如下程式碼(Create是在ActiveX控制元件中建立一個窗體對話方塊,IDD_VIEW_DIALOG就是剛剛新建的對話方塊):

 在OnSize函式編寫程式碼如下(MoveWindow是確定窗體對話方塊在ActiveX中的大小):

 第三:重新編譯,註冊ocx,使用ActiveX Control Test Container再次測試該控制元件

建立過程中遇到的問題總結:

1.建立完成後編譯時報錯 error C1189: #error :  Please use the /MD switch for _AFXDLL builds,解決辦法:右鍵專案,【屬性】-->【配置屬性】

-->【C/C++】-->【程式碼生成】-->【執行庫】,選擇如下選項:


2.按照上述文章建立完成後控制元件始終顯示不出來,經檢查,發現文章有一處程式碼漏掉了,在onDraw函式裡需要加入如下程式碼

void CHikControlCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (!pdc)
return;
// TODO: 用您自己的繪圖程式碼替換下面的程式碼。
//pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
//pdc->Ellipse(rcBounds);

m_ViewDialog.MoveWindow(rcBounds);
}


第二部分 海康威視ocx控制元件開發

首先在海康威視的官方網站下載SDK

http://www.hikvision.com/cn/download_61.html

解壓縮後,將標頭檔案和庫檔案都新增到工程中

右鍵-->【新增】-->【現有項】-->加入所需標頭檔案

右鍵-->【屬性】-->【配置屬性】-->【C/C++】-->【常規】

在【附加包含的目錄】里加入標頭檔案所在目錄

右鍵-->【屬性】-->【配置屬性】-->【連結器】-->【常規】

在【附加庫目錄】加入sdk庫目錄

右鍵-->【屬性】-->【配置屬性】-->【連結器】-->【輸入】

在【附加依賴庫】里加入

HCNetSDK.lib
ws2_32.lib

設計的控制元件介面如下:


在海康威視的sdk中有好幾個例子,藉助這些例子可以很容易完整相關的功能。

出過的問題:

1.做這個控制元件過程整個感受就是,類的新增也好,各種訊息事件的新增均通過右鍵-->【類嚮導】來完成比較好,一開始自己手動添加出了各種各樣的麻煩。

2.右鍵-->【屬性】-->【配置屬性】-->【常規】裡,字符集最好調整成【使用多位元組字符集】,不然呼叫sdk的函式時字元處理很麻煩。

3.呼叫messagebox時出現引數不匹配的情況,經過搜尋大致知道有messageboxA,messageboxW兩種情況,由於沒有做過MFC的開發,不是很清楚細節原因。