1. 程式人生 > >Qt 之 ActiveX控制元件跑官方例程記錄

Qt 之 ActiveX控制元件跑官方例程記錄

目錄(?)[-]

  1. 開發環境
  2. 基礎知識瞭解
  3. QT的ActiveX控制元件形式
  4. in-process執行的ActiveX server控制元件
  5. 獨立執行的ActiveX server控制元件

開發環境

win7 64+QT5.8.0 + MSVC2015_32/64

基礎知識瞭解

  1. ActiveX 是微軟針對網頁或其它應用呼叫而弄出來的,所以只能在IE中使用,firefox,chrome等不能用。所以,測試時請使用IE瀏覽器。
  2. 微軟的東西,由於一些相應的API的相容原因,無法用mingw版的編譯器編譯成功,編譯出來的exe也不能正常執行。
  3. 由於ActiveX的安全阻截,所以如果你做的外掛沒有相應認證需要設定下IE,關於IE的安全設定如下看著勾吧 
    這裡寫圖片描述

  4. ActiveX控制元件與一般的共享庫或程式一樣,要檢查其依賴是否完整,否則就要拷貝到一塊。可以使用depends.exe檢視,windeployqt.exe自動拷貝,在dll開發中有講不多說了。

  5. 微軟的IE中,HTML引入控制元件的方法(本來WEB開發小白,所以記錄下。)

      <object ID="OBject" 
      CLASSID="CLSID:控制元件的CLASSID號"
      CODEBASE="控制元件的cab檔案">
      [錯誤提示資訊]
      </object
    >
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5
    • ID:例項化的物件名 (必須)
    • CLASSID :外掛中例項化的類ID(必須)。
    • CODEBASE:如果本地登錄檔中沒有註冊該外掛,則需要它提供一個地址來下載該外掛的cab包(所以是非必須,只要你手動本地註冊或手動運行了該外掛服務就行。如何製作cab包另說【我的補充如何打cab包
    • 呼叫控制元件的方法,ID名就是物件名了,上面相當於例項化了一個控制元件中的類物件,可以直接呼叫其中的方法

      OBject.function(args);  
      • 1
      • 1

QT的ActiveX控制元件形式

QT的ActiveX控制元件有兩種形式,一種是DLL,一種是EXE。兩種形式的安裝執行不同

  1. DLL的安裝:

    • 使用微軟提供的工具 regsvr32,成功後可以用regedit查詢,可以直接寫個bat在dll外掛目錄下,就可以不用寫path路徑了。
    regsvr32 path\xxx.dll  安裝
    regsvr32 path\xxx.dll /u  解除安裝
    • 1
    • 2
    • 1
    • 2
    • 自己寫個安裝程式碼實現,跟呼叫dll一樣(我的補充:win32 控制檯程式即可,記得匯入 <windows.h>)。
    HMODULE dll = LoadLibrary("myserver.dll");
    typedef HRESULT(__stdcall *DllRegisterServerProc)();
    DllRegisterServerProc DllRegisterServer =
        (DllRegisterServerProc)GetProcAddress(dll, "DllRegisterServer");
    
    HRESULT res = E_FAIL;
    if (DllRegisterServer)
        res = DllRegisterServer();
    if (res != S_OK)
        // error handling
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  2. EXE的安裝執行 
    QT編譯出來的exe執行有兩種方式,一種是獨立執行,一種是像dll那樣類似先安裝後呼叫。 
    具體看後面的例程說明—獨立執行的ActiveX server控制元件


in-process執行的ActiveX server控制元件

此處以Hierarchy Example (ActiveQt) 為例說明(此例程巨集定義中有多餘的“;”,不刪除也能編譯通過,官方例程還出這種bug!!), 
在示例程式中搜索該專案,開啟構建,成功後一般生成的主要檔案是 .dll檔案,此時看輸出資訊會顯示“Server registered successfully!”說明IDC已經給我們註冊到系統中了,不信可以開啟登錄檔檢視。 
此時如果執行網頁,會發現什麼也沒有,控制元件沒有被載入進來。 
這是因為dll它所依賴的其它dll也不全,在系統路徑中找不到,所以載入不了。你手動註冊下也不會成功,那為什麼IDC能成功呢,因為IDC的環境變數中包含了QT庫呀。命令列執行下面的語句,路徑自己加,或者手動拷貝。dll齊全後再執行就OK了。

我的補充


windeployqt.exe xxx.dll
  • 1
  • 1

注意: 1.windeployqt的版本要選你編譯時的KIT選擇的版本。不然找的庫也不對。比如64位下的windeployqt他只找64位的庫,所以用depend.exe看沒毛病可執行起來依然不行。這問題讓我開始時完全找不到點上 
2.dll控制元件我用64位的msvc編譯出來可註冊,但執行不了,用32位就可以,無解。。。。。。。

獨立執行的ActiveX server控制元件

此處以OpenGL Example (ActiveQt)為例說明, 
在示例程式中搜索該專案,開啟構建,成功後一般生成主要檔案是 .exe檔案,可以單獨執行(手動點選exe執行時,必須把依賴dll都拷貝在一起,直接點QT裡的執行,它是自動加了QT庫到PATH中的,所以看似不需要dll), 此時如果執行HTML程式碼

  <SCRIPT LANGUAGE="JavaScript">
  function setRot( form )
  {
      GLBox.setXRotation( form.XEdit.value );
      GLBox.setYRotation( form.YEdit.value );
      GLBox.setZRotation( form.ZEdit.value );
  }
  </SCRIPT>

  <p />
  An OpenGL scene:<br />
  <object ID="GLBox" CLASSID="CLSID:5fd9c22e-ed45-43fa-ba13-1530bb6b03e0"
  CODEBASE="http://qt.nokia.com/demos/openglax.cab">
  [Object not available! Did you forget to build and register the server?]
  </object><br />

  <form>
  Rotate the scene:<br />
  X:<input type="edit" ID="XEdit" value="0" /><br />
  Y:<input type="edit" name="YEdit" value="0" /><br />
  Z:<input type="edit" name="ZEdit" value="0" /><br />
  <input type="button" value="Set" onClick="setRot(this.form)" />
  </form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

會顯示Object not available! Did you forget to build and register the server?,那是因為你還沒有以activex服務的形式執行控制元件openglax.exe,那如何執行?

有兩個方法:

  • 1 使用QT提供的小工具IDC註冊下(第一次構建成功後你開啟輸出會有提示:“Server registered successfully!”,這就是用IDC註冊成功了。)

    注:在非Qtcreator下執行時無論是想要註冊成功還是以activex形式單獨執行,都必須把依賴庫找齊才行。所以這裡雖然註冊成功了,但執行網頁依然不行。除非你弄齊了

  • 我的補充


  • 2 直接用命令列加引數執行外掛,regsvr32是無法註冊的。 
    看QT介紹.exe控制元件可以在其後新增命令引數。命令列可使用如下引數

    Option Result
    -regserver 註冊控制元件服務到系統登錄檔中,可以在regedit查尋到,註冊成功後可以在程式碼中指明CLSID就能呼叫了。 類似regsvr32 xx.dll
    -unregserver 從系統登錄檔中登出服務,登出後regedit自行刪除相應項。regsvr32 xx.dll /u
    -activex 以ActiveX控制元件服務的形式啟動該控制元件,這樣即使不註冊到系統登錄檔中,瀏覽器也可以呼叫該外掛,就是啟動速度慢。
    -dumpidl -version x.y Writes the server’s IDL to the specified file. The type library will have version x.y

為了方便驗證,使用第二種簡單,你可以先在Qtcreator專案配置中在command line arguments上加上 -activex,然後點選執行(F5)就OK了(注意要勾上add build library path to PATH,預設勾上的)。 

我的補充



此時在開啟測試網頁看是不是成功了,可能控制元件區一片白,滑鼠點選下就出來了,這種形式由於控制元件是單獨執行的,所以每次開啟頁面之前都要執行下openglax.exe才能顯示,不然不能載入外掛。 
如果不想這麼麻煩,那可以先用-regserver註冊openglax.exe外掛到系統登錄檔中,這樣也就和dll形式的外掛一樣了,而且明顯感覺到開啟速度很快。如果Qtcreator執行註冊成功了但依然不能顯示,那是因為qt更改了path的原因,所以能註冊,但執行網頁時沒有這個環境了,故你需要將依賴的dll和openglax.exe放到一塊,不然無法正常載入。 
兩種方式的網頁測試都不強求測試網頁要和外掛放在一塊,也不要求外掛非要放在系統目錄中,只是要求外掛和所需依賴要一起且齊全。因為Qtcreator執行時是加了path變數的,重要的事情強調下。 
此種形式無論是32還是64的編譯器都OK。 
演示如圖: 
這裡寫圖片描述

測試成功後再把依賴庫打包一起釋出吧。

開發環境

win7 64+QT5.8.0 + MSVC2015_32/64

基礎知識瞭解

  1. ActiveX 是微軟針對網頁或其它應用呼叫而弄出來的,所以只能在IE中使用,firefox,chrome等不能用。所以,測試時請使用IE瀏覽器。
  2. 微軟的東西,由於一些相應的API的相容原因,無法用mingw版的編譯器編譯成功,編譯出來的exe也不能正常執行。
  3. 由於ActiveX的安全阻截,所以如果你做的外掛沒有相應認證需要設定下IE,關於IE的安全設定如下看著勾吧 
    這裡寫圖片描述

  4. ActiveX控制元件與一般的共享庫或程式一樣,要檢查其依賴是否完整,否則就要拷貝到一塊。可以使用depends.exe檢視,windeployqt.exe自動拷貝,在dll開發中有講不多說了。

  5. 微軟的IE中,HTML引入控制元件的方法(本來WEB開發小白,所以記錄下。)

      <object ID="OBject" 
      CLASSID="CLSID:控制元件的CLASSID號"
      CODEBASE="控制元件的cab檔案">
      [錯誤提示資訊]
      </object>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5
    • ID:例項化的物件名 (必須)
    • CLASSID :外掛中例項化的類ID(必須)。
    • CODEBASE:如果本地登錄檔中沒有註冊該外掛,則需要它提供一個地址來下載該外掛的cab包(所以是非必須,只要你手動本地註冊或手動運行了該外掛服務就行。如何製作cab包另說【我的補充如何打cab包
    • 呼叫控制元件的方法,ID名就是物件名了,上面相當於例項化了一個控制元件中的類物件,可以直接呼叫其中的方法

      OBject.function(args);  
      • 1
      • 1

QT的ActiveX控制元件形式

QT的ActiveX控制元件有兩種形式,一種是DLL,一種是EXE。兩種形式的安裝執行不同

  1. DLL的安裝:

    • 使用微軟提供的工具 regsvr32,成功後可以用regedit查詢,可以直接寫個bat在dll外掛目錄下,就可以不用寫path路徑了。
    regsvr32 path\xxx.dll  安裝
    regsvr32 path\xxx.dll /u  解除安裝
    • 1
    • 2
    • 1
    • 2
    • 自己寫個安裝程式碼實現,跟呼叫dll一樣(我的補充:win32 控制檯程式即可,記得匯入 <windows.h>)。
    HMODULE dll = LoadLibrary("myserver.dll");
    typedef HRESULT(__stdcall *DllRegisterServerProc)();
    DllRegisterServerProc DllRegisterServer =
        (DllRegisterServerProc)GetProcAddress(dll, "DllRegisterServer");
    
    HRESULT res = E_FAIL;
    if (DllRegisterServer)
        res = DllRegisterServer();
    if (res != S_OK)
        // error handling
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  2. EXE的安裝執行 
    QT編譯出來的exe執行有兩種方式,一種是獨立執行,一種是像dll那樣類似先安裝後呼叫。 
    具體看後面的例程說明—獨立執行的ActiveX server控制元件


in-process執行的ActiveX server控制元件

此處以Hierarchy Example (ActiveQt) 為例說明(此例程巨集定義中有多餘的“;”,不刪除也能編譯通過,官方例程還出這種bug!!), 
在示例程式中搜索該專案,開啟構建,成功後一般生成的主要檔案是 .dll檔案,此時看輸出資訊會顯示“Server registered successfully!”說明IDC已經給我們註冊到系統中了,不信可以開啟登錄檔檢視。 
此時如果執行網頁,會發現什麼也沒有,控制元件沒有被載入進來。 
這是因為dll它所依賴的其它dll也不全,在系統路徑中找不到,所以載入不了。你手動註冊下也不會成功,那為什麼IDC能成功呢,因為IDC的環境變數中包含了QT庫呀。命令列執行下面的語句,路徑自己加,或者手動拷貝。dll齊全後再執行就OK了。

我的補充


windeployqt.exe xxx.dll
  • 1
  • 1

注意: 1.windeployqt的版本要選你編譯時的KIT選擇的版本。不然找的庫也不對。比如64位下的windeployqt他只找64位的庫,所以用depend.exe看沒毛病可執行起來依然不行。這問題讓我開始時完全找不到點上 
2.dll控制元件我用64位的msvc編譯出來可註冊,但執行不了,用32位就可以,無解。。。。。。。

獨立執行的ActiveX server控制元件

此處以OpenGL Example (ActiveQt)為例說明, 
在示例程式中搜索該專案,開啟構建,成功後一般生成主要檔案是 .exe檔案,可以單獨執行(手動點選exe執行時,必須把依賴dll都拷貝在一起,直接點QT裡的執行,它是自動加了QT庫到PATH中的,所以看似不需要dll), 此時如果執行HTML程式碼

  <SCRIPT LANGUAGE="JavaScript">
  function setRot( form )
  {
      GLBox.setXRotation( form.XEdit.value );
      GLBox.setYRotation( form.YEdit.value );
      GLBox.setZRotation( form.ZEdit.value );
  }
  </SCRIPT>

  <p />
  An OpenGL scene:<br />
  <object ID="GLBox" CLASSID="CLSID:5fd9c22e-ed45-43fa-ba13-1530bb6b03e0"
  CODEBASE="http://qt.nokia.com/demos/openglax.cab">
  [Object not available! Did you forget to build and register the server?]
  </object><br />

  <form>
  Rotate the scene:<br />
  X:<input type="edit" ID="XEdit" value="0" /><br />
  Y:<input type="edit" name="YEdit" value="0" /><br />
  Z:<input type="edit" name="ZEdit" value="0" /><br />
  <input type="button" value="Set" onClick="setRot(this.form)" />
  </form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

會顯示Object not available! Did you forget to build and register the server?,那是因為你還沒有以activex服務的形式執行控制元件openglax.exe,那如何執行?

有兩個方法:

  • 1 使用QT提供的小工具IDC註冊下(第一次構建成功後你開啟輸出會有提示:“Server registered successfully!”,這就是用IDC註冊成功了。)

    注:在非Qtcreator下執行時無論是想要註冊成功還是以activex形式單獨執行,都必須把依賴庫找齊才行。所以這裡雖然註冊成功了,但執行網頁依然不行。除非你弄齊了

  • 我的補充


  • 2 直接用命令列加引數執行外掛,regsvr32是無法註冊的。 
    看QT介紹.exe控制元件可以在其後新增命令引數。命令列可使用如下引數

    Option Result
    -regserver 註冊控制元件服務到系統登錄檔中,可以在regedit查尋到,註冊成功後可以在程式碼中指明CLSID就能呼叫了。 類似regsvr32 xx.dll
    -unregserver 從系統登錄檔中登出服務,登出後regedit自行刪除相應項。regsvr32 xx.dll /u
    -activex 以ActiveX控制元件服務的形式啟動該控制元件,這樣即使不註冊到系統登錄檔中,瀏覽器也可以呼叫該外掛,就是啟動速度慢。
    -dumpidl -version x.y Writes the server’s IDL to the specified file. The type library will have version x.y

為了方便驗證,使用第二種簡單,你可以先在Qtcreator專案配置中在command line arguments上加上 -activex,然後點選執行(F5)就OK了(注意要勾上add build library path to PATH,預設勾上的)。 

我的補充



此時在開啟測試網頁看是不是成功了,可能控制元件區一片白,滑鼠點選下就出來了,這種形式由於控制元件是單獨執行的,所以每次開啟頁面之前都要執行下openglax.exe才能顯示,不然不能載入外掛。 
如果不想這麼麻煩,那可以先用-regserver註冊openglax.exe外掛到系統登錄檔中,這樣也就和dll形式的外掛一樣了,而且明顯感覺到開啟速度很快。如果Qtcreator執行註冊成功了但依然不能顯示,那是因為qt更改了path的原因,所以能註冊,但執行網頁時沒有這個環境了,故你需要將依賴的dll和openglax.exe放到一塊,不然無法正常載入。 
兩種方式的網頁測試都不強求測試網頁要和外掛放在一塊,也不要求外掛非要放在系統目錄中,只是要求外掛和所需依賴要一起且齊全。因為Qtcreator執行時是加了path變數的,重要的事情強調下。 
此種形式無論是32還是64的編譯器都OK。 
演示如圖: 
這裡寫圖片描述

測試成功後再把依賴庫打包一起釋出吧。