Design and application of "reprint" COM component (ix)--idispatch interface for VC6.0

Source: Internet
Author: User

Original: http://vckbase.com/index.php/wv/1224.html

First, preface

Finally wrote the nineth time, I have been looking forward to writing this back, yes, why? Because automation (automation) is a very common, very useful, very exciting COM feature. Because WORD, EXCEL and other OFFICE software provides the "macro" function, even we use the VC development environment also provides "macro" function, more because of HTML, ASP, JSP and so on to rely on scripting (script) support, but also reflects the importance of automation interface.

If you are using the vc6.0 development environment, please continue reading.

If you use Vc.net 2003, please read the next one.

Second, IDispatch interface

In the case of a compiled language, we can have the compiler load the type library at compile time, which is the description of the loading interface. In the seventh article, we use #include method and #import method respectively to achieve this. Once the type library is loaded, the compiler knows how to compile the call to the interface function---this is called "pre-bind". However, if you want to use the component in a scripting language, the problem is big, because the scripting language is interpreted, and it executes without knowing the exact address of the function. The Automation interface was born---"post-bind".

The automation component is actually the component that implements the IDispatch interface. The IDispatch interface has 4 functions that interpret the language's executor to perform the functions provided by the component through the only 4 functions. The IDispatch interface is described in IDL form as follows: (note 1)

[Object, UUID (00020400-0000-0000-c000-000000000046),//IDispatch interface IID = IID_IDispatch pointer_default (unique) ]interface idispatch:iunknown{typedef [UNIQUE] IDispatch * lpdispatch;//goto definition IDispatch * for lpdispatch HRESULT Get Typeinfocount ([out] uint * pctinfo);//For these two functions of the type library, let's say later the HRESULT gettypeinfo ([in] uint Itinfo,[in] LCID Lcid,[out] ity    Peinfo * * pptinfo); HRESULT GetIDsOfNames (//Based on function name, get function ordinal (DISPID) [in] refiid riid, [In, size_is (cnames)] Lpole STR * Rgsznames, [in] UINT cnames, [in] lcid lcid, [out, size_is (cnames)] DIS    PID * rgdispid); [local]//local function HRESULT Invoke (//Based on function ordinal, explanation execution function function [in] DispID dispidmember, [in] refiid R                IID, [in] lcid lcid, [in] WORD wflags, [in, Out] dispparams * pdispparams, [out]      VARIANT * Pvarresult, [out] excepinfo * pexcepinfo,          [out]    UINT * puargerr); [Call_as (Invoke)]//remote version function HRESULT Remoteinvoke ([in] DispID dispidmember, [in] refiid Rii                D, [in] the LCID lcid, [in] DWORD dwFlags, [in] dispparams * pdispparams, [out] VARIANT * Pvarresult, [out] excepinfo * pexcepinfo, [out] UINT * Pargerr, [in ] UINT Cvarref, [In, size_is (CVARREF)] UINT * RGVARREFIDX, [in, Out, size_is (cvarref)] VARI Antarg * rgvarref);}

  

The above IDispatch interface function explanation, we leave to the back in the introduction. How do you implement these functions in a component program? Fortunately, fortunately, just like IUnknown, MFC and ATL have helped us finish. This time we focus on component authoring, and the next time we describe the component invocation method.

Iii. implementing automation components with MFC

I wrote this whole series of articles---"COM Component design and application", mostly using ATL to write component programs, but because automation is very useful, in the subsequent articles, but also to introduce the components of the "event" function, but also to explain how in MFC programs like WORD support "macro" function. These all need to use MFC, so give the reader a chatter:-)

3-1: Create a workspace (Workspace)

3-2: Build an MFC DLL project (project) with the project name "Simple5"

3-3: Be sure to choose Automation, remember! Remember!

3-4: Create a new class

3-5: Support Automation in new class

Class Information-name You write a name for yourself.

class Information-base class must derive from Ccomtarget, only it provides IDispatch support

Automation-none says it doesn't support automation, you have to choose it, it's all for nothing.

automation-automation supports automation, but cannot be instantiated directly. Later in the explanation of a number of IDispatch to use it, now do not worry.

automation-createable by Type ID must choose this project, so that we in the subsequent call, VB will be able to CreateObject (), VC will be able to createdispatch () on the Component object

have been instantiated. Note that this ID is actually the ProgID of the component.

3-6: Start ClassWizard, select Automation Card, prepare to build function

3-7: Add function. We're going to write an integer addition function add ().

3-8: Add another function Upper () to convert the string case. The function return value is a BSTR, this is no doubt, but the parameter type how incredibly is LPCTSTR? In COM, should a string not use a BSTR? Yes, a BSTR should be used, but since we are writing automation components with MFC, it helps us to convert between BSTR and LPCTSTR.

3-9: OK, let's start typing the program code:

Long Cdispsimple::add (long N1, long N2) {return n1 + N2;} BSTR cdispsimple::upper (lpctstr str) {CString strresult (str); Strresult.makeupper (); return strresult.allocsysstring ( );}

  

3-10: Compile Registration

If the above operation has been inadvertently wrong, then you can correct it by hand.

One, the Step <3-6> dialog window has "Delete" operation;

Second, you can open the ODL file (note 2) to modify, to be particularly careful in the declaration of the function, there is a [ID (n)] function ordinal, can not be messy;

The third, synchronously modifies the function declaration and the function body in the h/cpp;

Its four, in the CPP file, according to the situation also to modify the Begin_dispatch_map/end_dispatch_map () function mapping macro.

After compiling correctly, MFC does not automatically register like ATL. You need to manually perform Regsvr32.exe to register, or execute the menu "Tools\register control"

Iv. Implementing a dual Interface component with ATL (Refer to "COM Component design and application (v)" For instructions and procedures.)

4-1: Build an ATL project (project) with the project name "Simple6"

4-2: Press the default. Select DLL type, noncompliant proxy and stub code, MFC not supported, MTS not supported

4-3:new Atl Object ... Select Simple Object

4-4: Enter name and attribute, property by default, i.e. dual (dual interface) mode (Note 3)

4-5: Add function. In the ClassView card, select interface, right mouse button menu, Add Method ...

ADD ([in] Variant v1, [in] Variant v2, [out, retval] variant * pVal);

Upper ([in] BSTR str, [Out,retval] BSTR * PVal);

For the Add () function, you can still use the add ([in] long N1, [in] long N2, [out,retval] long * pVal) mode. But this time we did not use a long, but instead used the VARIANT to do the parameter and return value. Here I first sell a xiaoguanzi, look down, I know the use of the wonderful VARIANT of the place.

4-6: Complete code

STDMETHODIMP Cdispsimple::add (Variant V1, Variant V2, Variant *pval) {:: VariantInit (PVal);//Always initialize the return value is a good habit CComVariant V _1 (v1); CComVariant v_2 (v2); if ((V1.vt & VT_I4) && (V2.VT & VT_I4)//If all are integer types {//there is no use = = here, and operator & is used, you know Is that why?  V_1.changetype (VT_I4);//Convert to Integer v_2.changetype (VT_I4);//convert to Integer PVAL->VT = Vt_i4;pval->lval = V_1.lval + v_2.lVal;// Addition}else{v_1.changetype (VT_BSTR);//Convert to String V_2.changetype (VT_BSTR);//Convert to String CComBSTR BSTR (V_1.bstrval); BSTR. Appendbstr (v_2.bstrval);//String Connection PVAL->VT = Vt_bstr;pval->bstrval = BSTR. Detach ();} return S_OK;} STDMETHODIMP Cdispsimple::upper (BSTR Str, BSTR *pval) {*pval = null;//always initialize the return value is a good habit CComBSTR s (str); S.toupper ();//Convert to uppercase *pval = S.copy (); return S_OK;}

  

The Xiaoguanzi, which has just been sold, is now revealed ... The addition function add () does not use the long type, while the benefit of using a variant is that the function internally determines the parameter type, and if it is an integer, the integer addition, or string addition (string addition is the string join). In other words, if the parameter is a variant, then we can implement the variable parameter type of the function. It's a throat, it's cool!

V. Examples of calls in scripts

Open the Notepad program, enter the script, and save it as a Xxx.vbs file. Then in the Explorer you can double-click to run.

If you have the ability, you can also use JScript to write the above program, and then save as a xxx.js file, you can also run in the explorer. Another thing to say is that the Script program file icon (Win 2000) is, if you are not such (there is a software called "XX king梁肇new". The person writing this software is too low, it actually uses the. vbs extension file as its data stream file, which destroys the system default file type innuendo mode, cough ... ), you need to reset it by:

Vi. examples of use in WORD

6-1: Record a macro program

6-2: Choose "Keyboard", of course, you can also put this "macro" program on the "toolbar" up. Here we randomly specify a shortcut key, such as CTRL + Z

6-3: Start recording, below you casually input something. Then click "Stop".

6-4: Next, we execute the menu, select the macro that was just recorded, and then edit it

6-5: Click "Edit" button, enter the following program:

Do not explain, if you will be a little bit of VB, you can read this dongdong ha. Then save the editor that closes VBA (note 4).

6-6: Execute, execute, see what effect it is ...

Then press the shortcut key CTRL + Z

You have expanded the function of MS WORD, hey la la la la, Hey la la, the sky out of rosy clouds ah ... We just gave a simple example, in fact, this example does not have any practical significance, because the WORD itself has a case of the conversion function. But with this small example, you can realize the function of the automation component, is it enough?!

Vii. Summary

Not a summary! Hey...... Fooled,:-).

Note 1: Later we describe the interface functions, all using IDL form.

Note The 2:odl file is similar to IDL and is an interface file that MFC specifically describes for automation

Note 3: Dual interface, is a special interface to support the IDispatch interface, the following will be said

Note 4:vba is a language that specializes in Office development---Visual Basic for application

Design and application of "reprint" COM component (ix)--idispatch interface for VC6.0

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.