前言
在最近幾周的工作里,始終被一個(gè)頭疼的問題所困擾,那就是VB6編寫的ActiveX控件在Delphi環(huán)境下存在著諸多稀奇古怪的問題,幾經(jīng)周折,終于在搜索了幾乎全部的論壇、資料后,找到了針對(duì)不同Delphi版本發(fā)生的問題的解決辦法。
Delphi 5 莫名其妙的致命異常之一
首先,我們來看看VB寫的ActiveX控件在Delphi 5下面的奇怪表現(xiàn)。
例如:我們用VB編寫了一個(gè)控件UserTest(為簡(jiǎn)單起見,我們只導(dǎo)出一個(gè)類即用戶控件),一個(gè)屬性TestName,一個(gè)方法TestMethod。然后將其編譯成一個(gè)ActiveX控件,注冊(cè)并導(dǎo)入Delphi5的開發(fā)環(huán)境(以上步驟如有未清楚之處,請(qǐng)查閱各類參考資料,肯定有標(biāo)準(zhǔn)答案),到目前為止,看來一切正常。
然后,我們習(xí)慣的把控件拖放到窗體上,調(diào)整大小,在屬性窗口中為屬性賦值,或者在代碼中也是一樣,非常正常,好用的很。但是,下面問題來了,如果您興致勃勃的去調(diào)用了那個(gè)TestMethod,那么您將得到一個(gè)古怪的異常 “Ole Error 800a01a9”,然后程序退出,而且非常不幸的是,您將無法跟蹤到這個(gè)異常,在Delphi中或是VB中都是,當(dāng)然如果您對(duì)匯編很在行的話,您可以跟著Delphi的調(diào)試窗口一步一步往下……
當(dāng)我第一次碰到這個(gè)問題的時(shí)候,我?guī)缀跏菓嵟?,因?yàn)闊o論是MicroSoft或是Borland,對(duì)該錯(cuò)誤都沒有任何解釋,也沒有任何可以查找的資料。我只好跑到常去的幾個(gè)論壇,當(dāng)然最主要的還是CSDN,在VB版和Delphi版中四處搜索類似的問題,然后非常遺憾的是,只有類似的問題,而沒有答案,一個(gè)大客戶就用的這個(gè)開發(fā)工具,我在測(cè)試了幾乎所有Windows上的開發(fā)工具和開發(fā)環(huán)境(包括桌面和Web)后,惟獨(dú)將Delphi忘記了。
剩下的兩天里,我?guī)缀跏菨M世界亂跑,給所有的朋友打電話,詢問Delphi方面的高手是否知道這個(gè)情況,最后,我從Google上搜到了一個(gè)鏈接,可惜的是現(xiàn)在我忘記了那個(gè)鏈接的具體位置,但是我得到了一個(gè)近乎Magic的方法(發(fā)現(xiàn)者是這么稱呼它的):
一個(gè)手工修改Delphi導(dǎo)入VB ActiveX控件后產(chǎn)生的代理類型庫XXX_TLB.PAS(這里XXX指的是控件的類名)文件的方法可以解決這一問題。舉例說明:
有一個(gè)VB 寫的控件 UserControl1 ,在Delphi中導(dǎo)入后產(chǎn)生兩個(gè)文件,其中一個(gè)UserControl1_TLB.PAS 就是我們所要修改的文件。
在文件中查找 類似
FintF: _UserControl1;
Function GetControlInterface:_UserControl1;
和
property ControlInterface: _UserControl1 read GetControlInterface;
GetControlInterface;
以及
procedure TUserControl1.CreateControl;
procedure DoCreate;
begin
Finf:=IUnknown(OleObject) as _UserControl1;
End;
Begin
If Finf=nil then DoCreate;
End;
Function TUserControl1.GetControl1Interface: _UserControl1;
Begin
CreateControl;
Result:=Finfl;
End;
請(qǐng)注意:這里紅色標(biāo)出的 _UserControl1 要 全部換成 _ UserControl1Disp,如果編譯不成功的話,請(qǐng)將編譯警告中報(bào)出的_UserControl1 全部換成 _UserControl1Disp,編譯即可,這樣在調(diào)用控件的方法時(shí)便不會(huì)出現(xiàn)上述的致命錯(cuò)誤。
感謝這個(gè)偉大的發(fā)現(xiàn),我只能這么形容它,否則可能到現(xiàn)在我還要在這個(gè)圈子里套不出來,或者就是使用另外的工具重新開發(fā)這個(gè)控件(我難以想象這個(gè)工作量會(huì)有多大,又或者它可能還會(huì)存在其他的兼容性問題)。
在最近幾周的工作里,始終被一個(gè)頭疼的問題所困擾,那就是VB6編寫的ActiveX控件在Delphi環(huán)境下存在著諸多稀奇古怪的問題,幾經(jīng)周折,終于在搜索了幾乎全部的論壇、資料后,找到了針對(duì)不同Delphi版本發(fā)生的問題的解決辦法。
Delphi 5 莫名其妙的致命異常之一
首先,我們來看看VB寫的ActiveX控件在Delphi 5下面的奇怪表現(xiàn)。
例如:我們用VB編寫了一個(gè)控件UserTest(為簡(jiǎn)單起見,我們只導(dǎo)出一個(gè)類即用戶控件),一個(gè)屬性TestName,一個(gè)方法TestMethod。然后將其編譯成一個(gè)ActiveX控件,注冊(cè)并導(dǎo)入Delphi5的開發(fā)環(huán)境(以上步驟如有未清楚之處,請(qǐng)查閱各類參考資料,肯定有標(biāo)準(zhǔn)答案),到目前為止,看來一切正常。
然后,我們習(xí)慣的把控件拖放到窗體上,調(diào)整大小,在屬性窗口中為屬性賦值,或者在代碼中也是一樣,非常正常,好用的很。但是,下面問題來了,如果您興致勃勃的去調(diào)用了那個(gè)TestMethod,那么您將得到一個(gè)古怪的異常 “Ole Error 800a01a9”,然后程序退出,而且非常不幸的是,您將無法跟蹤到這個(gè)異常,在Delphi中或是VB中都是,當(dāng)然如果您對(duì)匯編很在行的話,您可以跟著Delphi的調(diào)試窗口一步一步往下……
當(dāng)我第一次碰到這個(gè)問題的時(shí)候,我?guī)缀跏菓嵟?,因?yàn)闊o論是MicroSoft或是Borland,對(duì)該錯(cuò)誤都沒有任何解釋,也沒有任何可以查找的資料。我只好跑到常去的幾個(gè)論壇,當(dāng)然最主要的還是CSDN,在VB版和Delphi版中四處搜索類似的問題,然后非常遺憾的是,只有類似的問題,而沒有答案,一個(gè)大客戶就用的這個(gè)開發(fā)工具,我在測(cè)試了幾乎所有Windows上的開發(fā)工具和開發(fā)環(huán)境(包括桌面和Web)后,惟獨(dú)將Delphi忘記了。
剩下的兩天里,我?guī)缀跏菨M世界亂跑,給所有的朋友打電話,詢問Delphi方面的高手是否知道這個(gè)情況,最后,我從Google上搜到了一個(gè)鏈接,可惜的是現(xiàn)在我忘記了那個(gè)鏈接的具體位置,但是我得到了一個(gè)近乎Magic的方法(發(fā)現(xiàn)者是這么稱呼它的):
一個(gè)手工修改Delphi導(dǎo)入VB ActiveX控件后產(chǎn)生的代理類型庫XXX_TLB.PAS(這里XXX指的是控件的類名)文件的方法可以解決這一問題。舉例說明:
有一個(gè)VB 寫的控件 UserControl1 ,在Delphi中導(dǎo)入后產(chǎn)生兩個(gè)文件,其中一個(gè)UserControl1_TLB.PAS 就是我們所要修改的文件。
在文件中查找 類似
FintF: _UserControl1;
Function GetControlInterface:_UserControl1;
和
property ControlInterface: _UserControl1 read GetControlInterface;
GetControlInterface;
以及
procedure TUserControl1.CreateControl;
procedure DoCreate;
begin
Finf:=IUnknown(OleObject) as _UserControl1;
End;
Begin
If Finf=nil then DoCreate;
End;
Function TUserControl1.GetControl1Interface: _UserControl1;
Begin
CreateControl;
Result:=Finfl;
End;
請(qǐng)注意:這里紅色標(biāo)出的 _UserControl1 要 全部換成 _ UserControl1Disp,如果編譯不成功的話,請(qǐng)將編譯警告中報(bào)出的_UserControl1 全部換成 _UserControl1Disp,編譯即可,這樣在調(diào)用控件的方法時(shí)便不會(huì)出現(xiàn)上述的致命錯(cuò)誤。
感謝這個(gè)偉大的發(fā)現(xiàn),我只能這么形容它,否則可能到現(xiàn)在我還要在這個(gè)圈子里套不出來,或者就是使用另外的工具重新開發(fā)這個(gè)控件(我難以想象這個(gè)工作量會(huì)有多大,又或者它可能還會(huì)存在其他的兼容性問題)。