ActiveX控件是帶有IDispatch接口的COM組件,我現在想寫一個客戶程序把ActiveX控件作為進程內的組件並調用其方法(通過IDispatch::Invoke函數),可具體如何寫代碼不太清楚,望高手指點一二。
5 个解决方案
你的客戶端是用什么編寫?C++,Delphi, VB?如果是,則用VTBL調用應該比調用IDispatch::Invoke容易得多,直接倒入類型庫就可以了。
如果是VBScript、ASP,則更加簡單直接在點'.'后面加方法名即可。我不知道有什么情況下,需要直接調用Invoke函數。除了編譯器和宏解釋器,而且大多數編譯器對Invoke的實現也不是自己寫的,都是用ITypeInfo::Invoke來實現。如果用C++來調用Invoke是一件很...丑陋的事情。如果你一定要看,《Inside COM+ base service》一書中有介紹。
我的感覺是,你對ActiveX的IDispatch有誤解。IDispatch並不是因為Invoke才存在,而是因為ASP,VBScript,JaveScript等宏語言才存在。Invoke應該有宏解釋器來調用,而不是客戶端代碼。
C++、VB、Object Pascal等支持前綁定的語言是用不到Invoke的,特別是在分布式環境下,IDispatch的Invoke方法幾乎是性能的大敵。大多數組件支持IDispatch是因為考慮到支持宏語言(特別是ASP),Invoke存在並不意味着必須用它,很少有客戶端會直接調用到Invoke方法。
請問zcheny我#import了控件的類型庫后如何創建這個控件?我好象記得不是用CoCreateInstance的。
#import關鍵字,主要是為了自動生成C++里面的智能指針、IID、CLSID,以及對[out,retval]、封裝異常的函數;(當然這也要看#import后面的其他關鍵字,如named_guids,raw_interface_only, no_namespace等等)。注意#import產生的.tlh和.tli文件是包含在一個namespace名字空間里的,簡單起見可以使用no_namespace,否則...編譯器會報找不着...符號等等錯誤。
#import之后,可以使用智能指針的CreateInstance方法,也可以使用CoCreateInstance。
使用智能指針可以使COM編程的日子好過一些。
我的意思是,ATL中有CreateControl這個函數來創建控件而不是CoCreateInstance或CreateInstance,不知道CreateControl背后是什么一個機制呢?是不是調用了CoCreateInstance?