注冊 登錄
Office中國論壇/Access中國論壇 返回首頁

ganlinlao的個人空間 http://m.mzhfr.cn/?230471 [收藏] [復(fù)制] [分享] [RSS]

日志

FreeBasic調(diào)用COM組件

熱度 1已有 4411 次閱讀2015-5-28 12:56 |個人分類:FreeBasic| Freebasic與com

com的復(fù)雜性,有點超出我的想象。

與其說Freebasic與vb的互動,不如說Freebasic與com的關(guān)系。
Freebasic如何調(diào)用com呢?Freebasic如何編寫com呢?
Freebasic編譯com,一個很明顯的意義,就是在64位中,為VBA提供類庫。
基礎(chǔ)知識:
1、數(shù)據(jù)類型的轉(zhuǎn)換:VBA的string全稱是BSTR。這是VBA獨(dú)有。VBA的數(shù)組,全稱safeArray。vba的variant,是一個復(fù)合型的數(shù)據(jù)結(jié)構(gòu)。
2、COM組件
com(Component Object Model組件對象模型)是開發(fā)軟件組件的一種方法。
com組件實際上是一些小的二進(jìn)制可執(zhí)行程序,它們可以給應(yīng)用程序,操作系統(tǒng)以及其他組件提供服務(wù)。
在COM構(gòu)架下,人們可以開發(fā)出各種各樣的功能專一的組件,然后將它們按照需要組合起來,構(gòu)成復(fù)雜的應(yīng)用系統(tǒng)。
可以在多個應(yīng)用系統(tǒng)中重復(fù)利用同一個組件;可以方便的將應(yīng)用系統(tǒng)擴(kuò)展到網(wǎng)絡(luò)環(huán)境下;COM具有與語言,平臺無關(guān)的特性。

CLSID與ProgID
每個COM接口和組件類都有一個全球唯一的標(biāo)識符GUID,接口的標(biāo)識符叫做IID,組件類的標(biāo)識符叫CLSID(其實都是GUID),組件類還可以用一個別名ProgID來標(biāo)識,
ProgID由類名+工程名組成,例如flash控件的ProgID: "ShockwaveFlash.ShockwaveFlash"

動態(tài)接口、靜態(tài)接口
com有兩種類型的接口,一種是動態(tài)語言用到的IDispatch接口,一種是靜態(tài)語言用到的靜態(tài)接口.
我們將IDispatch接口稱為動態(tài)接口,而非IDispatch類接口稱為靜態(tài)接口.

動態(tài)接口:IDispatch接口對象。vba中使用createobject創(chuàng)建對象(俗稱晚期綁定)用的就是Idispatch接口。

靜態(tài)接口:基于IUnknown指針實現(xiàn)的非IDispatch接口。vba并不支持指針,所以vba通過引用tlb進(jìn)行轉(zhuǎn)換(俗稱前期綁定)。vba中無法直接使用iunkown。

Vtable方式:這是性能最好的訪問com的方式,不過必須對指針和com有著相當(dāng)深的了解,才能用好它。否則很容易出錯。

Freebasic提供了全部的三種訪問com的方式。一般情況下,最好使用Idispatch和Iunknown方式。


接下來我要介紹的axsuite3庫,很重要,對于使用freebasi訪問com組件有很大的便利。(記住,訪問com組件和編寫com組件難度是很不一樣的,后者要難得多了)
如果和aauto的com庫比較起來,坦白地說,axsutite3封裝得不太好,起碼不夠直觀和不夠OOP。略表遺憾。
當(dāng)你使用ocx的控件時,axsuite要求你的系統(tǒng)上要有ATL.dll(或Atl71.DLL),換句話說,axsuite是以ATL方式實現(xiàn)對com的使用。

函數(shù):
Sub AxInit(ByVal Host As Integer=False)
說明:初始化axsuite。如果要調(diào)用的ocx等窗體控件,則host=true,如果是普通的非窗體的com組件,則host為false
如:Axinit(True)

Function AxCreateObject overload(strProgID1 AS string, strIID1 AS string = "") as any ptr
說明:創(chuàng)建對象。Progid或IID都是string
如:excelApp=AxCreateObject("excel.applicaiton")
       excelApp=AxCreateObject("{8E27C92B-1264-101C-8A2F-040224009C02}",{8E27C92C-1264-101C-8A2F-040224009C02}")

 
Function  AxCreateObject overload( hwnd_control as hwnd) as any ptr
說明:直接通過系統(tǒng)分配的hwnd,來創(chuàng)建窗體類的com對象。
如: ocxPtr=axCreateobject(hwnd)

Sub AxReleaseObject(byVal Objptr as any ptr)
說明:釋放對象。相當(dāng)于vba中的set object=nothing (即引用數(shù)-1)

Function AxCreateControlLic (ByVal strProgID AS lpOLEStr, byval hWndControl AS hwnd, byval strLicKey AS lpwstr) AS Long
說明:用于帶有License Key的com對象。這在天朝中,估計用得很少了。

Function AxCreateUnreg(ByVal hdll As HMODULE, byval CLSIDS As string, byval IIDS As string,ByVal hWndControl AS hwnd = 0) as any ptr
說明:創(chuàng)建一個免注冊的com對象或ocx對象。

Sub setObj(byval pxface as uinteger ptr,ByVal pThis as uinteger)

Sub setVObj(byval pxface as uinteger ptr,ByVal vThis as variant)

Function ToBSTR(cnv_string As String) As BSTR
說明:將Freebasic的string轉(zhuǎn)換成VB的Bstr字符串
如: dim myBstr as bstr=ToBstr("Test string")

Function FromBSTR(ByVal szW As BSTR) As String
說明:將vb的bstr轉(zhuǎn)換成freebasic的string。

Function VariantS(ByRef v As variant)As String
說明:將variant中的bstr轉(zhuǎn)換成freebasic的string。

Function VariantB(ByRef v As variant)As bstr
 說明:將variant中的bsctr轉(zhuǎn)換成單純的bstr。相當(dāng)于vba中的cstr(variant)

Function VariantV(ByRef v As variant)As Double
說明:將variant中的數(shù)字轉(zhuǎn)換成double。?不知道會不會帶來什么不可預(yù)測的后果。數(shù)字類型那么多種。

Function Vptr(Byval x As Any Type*) As Variant Ptr
說明:將Freebasic的任何一種數(shù)據(jù)類型轉(zhuǎn)換成variant的指針。
如:Dim vVar As Variant
vVar=*vptr(20) : vVar=*vptr(20.5) : vVar=*vptr(“Hello there”)

VLet (As variant, x As Any Type*)  
說明: 這是一個 宏macro 等價 Vptr 函數(shù),可以直接使用。編譯器會自動轉(zhuǎn)成vptr
用這個宏函數(shù),會顯得更直觀。
如:Dim vVar As Variant : Vlet(vVar, 12.75) : Vlet(vVar, “Test String”)
類似這樣的有用宏函數(shù)還有:
toVariant(x) :這里的x as any  type
Ax_FreeStr(bs) :為Bstr字符串分配內(nèi)存
Kill_Bstr(bs):將Bstr字符串從內(nèi)存中刪除。
以上宏函數(shù)都可以在代碼中直接使用。
*any type 是指下面這些數(shù)據(jù)類型: (variant/string/byte/short/Integer/Longint/single/Double/BSTR/Ubyte/Uinteger/Ulongint/Ushort/Ubyte)

**************************************
接下來這部分,是有點悲催的封裝
***************************************
axsuite3中使用Idispatch訪問com組件的函數(shù):
Sub AxCall (ByRef pmember as tmember,...)
說明:寫或設(shè)置Idispatch的屬性值。(注:這樣的封裝方式有點怪)

Function AxGet (ByRef pmember as tmember,...)as variant
說明:獲取Idispatch的方法的返回值,或獲取Idispatch的屬性值

Vtable方式訪問com組件:
Obj->lpVtbl->Method(Obj,…)
RetValue=Obj->lpVtbl->Method(Obj,…)
如:
scode=dx->lpvtbl->Direct3DCreate(dx,@d3d)   '獲取Direct3D的接口
d3d->lpvtbl->GetAdapterDisplayMode(d3d,D3DADAPTER_DEFAULT,@DispMode)




**************************************
Axsuite中使用Ocx控件的一些輔助手段:
Function  AxWinFull(byVal h_parent as hwnd, name1 as string, progid as string, _
x as integer, y as integer, w as integer, h as integer, style as integer = WS_visible or WS_OVERLAPPEDWINDOW, exstyle as integer = 0) as hwnd

說明:在vb中使用Ocx,我們都知道ocx必須放在form中才能使用,ocx無法單獨(dú)使用。
          這說明ocx必須要有一個窗口容器。
         本函數(shù)就是用于創(chuàng)建一個普通窗體,作為ocx控件的容器。并返加一個窗口句柄
     

Function  AxWinTool(byVal h_parent as hwnd, name1 as string, progid as string, _
 x as integer, y as integer, w as integer, h as integer, style as integer = WS_visible, exstyle as integer = WS_EX_TOOLWINDOW ) as hwnd

說明:創(chuàng)建一個工具條,作為ocx控件的窗口容器。

Function  AxWinChild(byVal h_parent as hwnd, name1 as string, progid as string, _
x as integer, y as integer, w as integer, h as integer,style as integer = WS_visible or WS_child or WS_border, exstyle as integer = 0 ) as hwnd

說明:創(chuàng)建一個子窗體,作為ocx控件的容器
注:h_parent指窗體的句柄,name1是指窗體的名稱,progid指ocx的progid,
x,y指窗體的左上角的坐標(biāo)位置,w,y分別是窗體的寬度和高度。style,exstyle詳見api教程。

Sub AxWinKill(byVal h_Control as hwnd)
說明:銷毀窗體。關(guān)閉窗口時,必須銷毀窗體
Sub AxWinHide(byVal h_Control as hwnd, byVal h_Parent as hwnd = 0)
隱藏控件和窗體

Sub AxWinShow(byVal h_Control as hwnd, byVal h_Parent as hwnd = 0)
顯示控件和窗體

Function  AxWinUnreg(byVal h_parent as hwnd, x as integer, y as integer, w as integer, h as integer, style as integer = WS_visible or WS_child or WS_border, exstyle as integer = 0) as hwnd

說明:免注冊使用ocx控件時,創(chuàng)建一個普通窗體作為Ocx的容器。

發(fā)表評論 評論 (1 個評論)

回復(fù) tmtony 2015-6-3 14:18
強(qiáng)!

facelist doodle 涂鴉板

您需要登錄后才可以評論 登錄 | 注冊

QQ|站長郵箱|小黑屋|手機(jī)版|Office中國/Access中國 ( 粵ICP備10043721號-1 )  

GMT+8, 2025-7-13 03:12 , Processed in 0.068490 second(s), 18 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

返回頂部