Mostafa Attariani >From: "Ehsan Akhgari" <[EMAIL PROTECTED]> >Reply-To: [EMAIL PROTECTED] >To: <[EMAIL PROTECTED]> >Subject: RE: [msvc] Using #import >Date: Fri, 5 Dec 2003 22:02:21 +0330 > > > I have a control, call it MyControl.ocx. It therefore has a type > > library, MyControl.tlb. > >Let's assume that your control provides a dual interface (a custom interface >derived from IDispatch) and that interface is called IMyControl. > > > I can use VC 6's ClassWizard to create wrapper classes for that type > > library, which is great - but since this control of mine is still in > > development (I'm experimenting, and testing the control as I go), the > > contents often change and thus I would need to keep recreating it - > > deleting the old files first, probably. > >This method uses the IDispatch part of the interface, which is less >efficient than direct virtual function calls you can use on a dual >interface. > > > If I use this method, I can declare and use objects of type > > _DMyControl with no problems. > > > > So I was trying to use something new (to me): #import. The import > > itself, and the creation of the .tlh and .tli files, went OK; but I'm > > struggling to be able to declare and use the object wrapping the type > > library. Looking in the .tlh, it declares structs. One is _DMyControl, > > derived from IDispatch, which sounds familiar; the other is plain > > MyControl. > >First of all, beware of the namespace problem. Unless you use #import with >no_namespace, it declares and defines everything inside namespace >TYPELIBRARY_NAME. > >Now, the _DMyControl interface should logically not used unless your >control's interface is not dual (which is should be, by all means). >Usually, in the #import world, the _DXXX interfaces are used for handling >events using connection points. > >The MyControl class forward declaration is only there to enable __uuidof(). >It should look like this: > > class __declspec(uuid("...")) MyControl; > >Which enables you to write __uuidof(MyControl) instead of CLSID_MyControl. >This is useful in template coding, but I personally prefer #import with >named_guids which creates the CLSID_MyControl variant as well. > > > If I try to declare and use a MyControl object, the compiler complains > > of "... uses undefined type MyControl" (it is a forward reference > > only, no body). > >Yup, like I said, MyControl is *only* intended to be used with __uuidof(). > > > If I try to declare and use a _DMyControl object, it complains of "... > > cannot instantiate abstract class _DMyControl because of..." > > and then it lists functions such as QueryInterface(), AddRef(), etc. > >_DMyControl should be like this (correct me if I'm wrong): > > struct _DMyControl : IDispatch {}; > >It's not very useful, I guess. > > > So based on the name MyControl.tlb, what class should I be declaring > > my objects as? The ClassWizard method gives me something derived from > > COleDispatchDriver, which allows me to use AttachDispatch() to connect > > an IDispatch to (some members may remember a question from a while > > back about one control using another). > > > > If I could just figure out how to use #import's results properly I > > think I'd be onto a winner. > >COleDispatchDriver is a manipulator for IDispatch-based interfaces. The >class ClassWizard creates has member functions with the same name as the >methods of the control, and internally, they all use IDispatch::Invoke( ) >with a magic number DISPID and all the gory stuff - something you wouldn't >want to do with hand. > >Now, what will help you is the #import-generated classes around the non-dual >part of your interface. First, there will be a raw IMyControl interface >definition, and also, a wrapper named IMyControlPtr. The last one is a >smart pointer based on _com_ptr_t, and is the one you should usually use. >Now, all the original virtual member functions named xxx can be access via >the raw_xxx methods of these wrappers, and also, they can be used with a >simplified VB-like syntax using the same 'xxx' name. > > // example: > IMyControlPtr ptr; > // somehow point it to your control (see below) // access the Name >property _bstr_t theName = ptr->Name; // set it ptr->Name = "my name"; >// access the Foo method (taking a BSTR and an int param, and returning a >float): > float result = ptr->Foo( "string", 0 ); > >All HRESULT error codes will be converted to _com_error exceptions, so you >should wrap these calls in a try/catch block. > >Now, how you're supposed to point an IMyControlPtr to your control? Just >act like before: obtain an IDispatch pointer to your control in whatever way >you used to, and QueryInterface( ) it for IMyControl, and then, pass in in >the IMyControlPtr's ctor, or as a param to IMyControlPtr::Attach( ) method. >See, it's just as simple as what you were doing by the ClassWizard-generated >class. > >Hope this helps, >------------- >Ehsan Akhgari > >List Owner: [EMAIL PROTECTED] > >[ Email: [EMAIL PROTECTED] ] >[ WWW: http://www.beginthread.com/Ehsan ] > >Light without eyes illuminates nothing. > > > > >_______________________________________________ >msvc mailing list >[EMAIL PROTECTED] >See http://beginthread.com/mailman/listinfo/msvc_beginthread.com for subscription changes, and list archive.
Take advantage of our best MSN Dial-up offer of the year � six months @$9.95/month. Sign up now!
