QT中使用ActiveX控制元件、QAxBase、QAxWidget

pamxy發表於2013-07-28

轉自:http://blog.const.net.cn/a/10271.htm

QaxContainer模組是訪問ActiveX控制元件和COM物件的一個Windows擴充套件。QAxContainer模組是ActiveQt構架的一部分。它提供一個庫,由擔當ActiveX控制元件容器角色的QWidget的子類Q...


QaxContainer模組是訪問ActiveX控制元件和COM物件的一個Windows擴充套件。

    QAxContainer模組是ActiveQt構架的一部分。它提供一個庫,由擔當ActiveX控制元件容器角色的QWidget的子類QAxWidget 和 用來簡化訪問非視覺化COM物件的QObject的子類QAxWidget 實現。通過類QAxScript, QAxScriptManager和QAxScriptEngine可以解釋嵌入的COM物件,還有一個工具集使得程式設計訪問COM物件更容易。

    模組由6個類構成:
        1. QAxBase 是一個提供用來初始化和訪問一個COM物件及ActiveX控制元件的API的抽象類。
        2. QAxObject是一個包裝了COM物件的QObject。
        3. QAxWidget 是一個包裝了ActiveX控制元件的QWidget。
        4. QAxScriptManager, QAxScript 和 QAxScriptEngine provide an interface to the Windows Script Host.

Some example applications that use standard ActiveX controls to provide high-level user interface functionality are provided.
提供了一些使用標準ActiveX控制元件來提供高階使用者介面功能的示例。
The QAxContainer module is part of the Qt Desktop Edition for Windows. It is not part of the Qt Open Source Edition.
=====================================================

1. 使用庫

    構造使用COM物件和ActiveX控制元件的Qt應用程式,需要向.pro檔案中加入
            CONFIG += qaxcontainer
來連線到QAxContainer模組

1.1. 配置QAxContainer應用程式

    QaxContainer庫是靜態的,因此使用這個模組的時候不需要重新分配任何額外的檔案。但要注意,你所使用的提供ActiveX服務的二進位制檔案必須被安裝在目標系統中,因此你需要把它們裝在你的釋出包中並在你的應用程式安裝過程中為它們註冊。


2. 初始化COM物件

     可以通過使用QAxBase::setControl() 或 直接把物件的名字傳到QAxBase子類的構造器中 來初始化一個COM物件。

     控制元件能通過多種格式指定,但最快且功能最強的格式是直接使用物件的Class ID(CLSID)。 Class ID能考慮到這個物件涉及別的機器時資訊的變化,而且能為需要license的控制元件包括一個license key。

2.1. 典型的錯誤資訊

    ActiveQt在執行中遇到錯誤時會向debug output顯示錯誤資訊。通常要在偵錯程式下執行你的程式來檢視這些資訊(e.g. in Visual Studio's Debug output)。

    -- Requested control could not be instantiated
                The control requested in QAxBase::setControl() is not installed on this system, or is not accessible for the current user.     The control might require administrator rights, or a license key. If the control is licensed, pass the license key to QAxBase::setControl as documented.


3. 訪問物件API

模組提供了訪問COM物件的Qt API來取代COM的資料型別。

有4種方法去呼叫訪問COM物件的API:
         • Generating a C++ namespace
         • Call-by-name
         • Through a script engine
         • Using the native COM interfaces

3.1. 生成 C++ Namespace

    用dumpcpp 工具可以為想要訪問的型別庫生成一個C++名空間。需要手動對你要用的型別庫使用這個工具, 或者也可以通過向.pro檔案中的變數TYPELIBS新增型別庫來把它整合到編譯系統中:
            TYPELIBS = file.tlb
注意,dumpcpp不一定能列出型別庫中所有的API。
把生成的標頭檔案包含進你的程式碼中,通過生成的C++類來訪問物件API。 更多資訊可以參考示例Qutlook。

3.2. Call-by-Name

    用QAxBase::dynamicCall()、QAxBase::querySubObject() 和QObject::setProperty()、QObject::property() 能通過名字呼叫COM物件的方法和屬性。用dumpdoc工具能獲得COM物件和他的字物件的Qt API文件。注意不是所有的COM物件的API是可用的。
更多請參看示例Webbrowser。

3.3. Calling Function Through a Script Engine

    Qt應用程式能使用安裝在系統上的任何ActiveScript engine。Script engine能執行指令碼程式碼去訪問COM物件。

    使用script engine時,用QAxScriptManager::addObject()註冊你想通過指令碼訪問的COM物件,用QAxScriptManager::load()把script程式碼裝入引擎。接著就可以用QAxScriptManager::call() 或 QAxScript::call()來呼叫script函式。

    COM物件的API結束了指令碼對所使用的指令碼語言的依賴。
    ActiveX Test Container 示範瞭如何裝載指令碼檔案。

3.4. Calling a Function Using the Native COM Interfaces

    上面的方法都不能訪問的COM物件函式,可以直接用QAxBase::queryInterface()去查詢COM介面。它可以獲得控制元件的型別庫中用#import標示的各個介面類的C++定義;更多的細節請看你的編譯器手冊。

3.5. 典型的錯誤資訊

    ActiveQt在執行中遇到錯誤的時候會向debug output顯示錯誤資訊。通常你必須在偵錯程式下執行你的程式來檢視這些資訊(e.g. in Visual Studio's Debug output)。

    -- QAxBase::internalInvoke: No such method
            A QAxBase::dynamicCall() failed - the function prototype did not match any function available in the object's API.

    -- Error calling IDispatch member: Non-optional parameter missing
            A QAxBase::dynamicCall() failed - the function prototype was correct, but too few parameters were provided.

    -- Error calling IDispatch member: Type mismatch in parameter n
            A QAxBase::dynamicCall() failed - the function prototype was correct, but the paramter at index n was of the wrong type and could not be coerced to the correct type.

    -- QAxScriptManager::call(): No script provides this function
            You try to call a function that is provided through an engine that doesn't provide introspection (ie. ActivePython or ActivePerl). You need to call the function directly on the respective QAxScript object. 

相關文章