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!

Reply via email to