COM Component Design and Application 9-idispatch interface for vc6.0

Source: Internet
Author: User
Download source code

I. Preface
I finally wrote it to the ninth time, and I have been hoping to write this article. Why? Automation is a very common, useful, and wonderful com function. Since office software such as Word and Excel provide the "macro" function, even the VC development environment we use provides the "macro" function, because HTML, ASP, JSP, and so on all rely on script support, it reflects the importance of automated interfaces.
If you are using the development environment of vc6.0, please continue to read.
If you are using vc.net 2003, read the next one.

Ii. idispatch Interface
If it is a compilation language, we can let the compiler load the Type Library during compilation, that is, the description of the loading interface. In the seventh article, we used the # include method and # import method respectively. After the Type Library is loaded, the compiler will know how to compile the interface function call --- this is called "pre-binding ". However, if you want to use components in the script language, the problem is big. Because the script language is interpreted and executed, it does not know the specific function address during execution. What should you do? The automated interface was born-"post-binding ".
Automated components are actually components that implement the idispatch interface. The idispatch interface has four functions. The Interpreter executes the functions provided by the component through the only four functions. The idispatch interface is described in the IDL format as follows: (Note 1)

[Object, UUID (UID), // IID = iid_idispatch pointer_default (unique)] interface idispatch: iunknown {typedef [unique] idispatch * lpdispatch; // convert idispatch * To lpdispatch hresult gettypeinfocount ([out] uint * pctinfo); // the two functions related to the type library, let's talk about hresult gettypeinfo ([in] uint itinfo, [in] lcid, [out] itypeinfo ** pptinfo); hresult getidsofnames (// according to the function name, obtain the function serial number (dispid) [in] refiid riid, [in, size_is (cnames)] lpolestr * rgsznames, [in] uint cnames, [in] lcid, [out, size_is (cnames)] dispid * rgdispid); [local] // the local version of the function hresult invoke (// according to the function serial number, explain the function execution function [in] dispid dispidmember, [in] refiid riid, [in] lcid, [in] Word wflags, [In, out] dispparams * pdispparams, [out] variant * pvarresult, [out] callback info * p1_info, [out] uint * puargerr); [call_as (invoke)] // remote function hresult remoteinvoke ([in] dispid dispidmember, [in] refiid riid, [in] lcid, [in] DWORD dwflags, [in] dispparams * pdispparams, [out] variant * pvarresult, [out] partition info * p1_info, [out] uint * pargerr, [in] uint cvarref, [in, size_is (cvarref)] uint * rgvarrefidx, [in, out, size_is (cvarref)] variantarg * rgvarref );}

The above idispatch interface function is described in the next step. How can we implement these functions in component programs? Okay, okay. Just like iunknown, both MFC and ATL have helped us. This section focuses on the compilation of components. The next section describes the call methods of components.

Iii. use MFC to implement automated components
The entire series of articles I wrote, "COM Component Design and Application", mostly Use ATL to write component programs. However, automation is very useful. In subsequent articles, we also want to introduce the "event" function of the component and how to support the "macro" function like word in the MFC program. All of these require the use of MFC, so I will give the reader an answer :-)
3-1: Create a workspace)
3-2: Create an mfc dll project named "simple5"

3-3: Be sure to select automation. Remember! Remember!

3-4: create a new class

3-5: supports automation in the new class

Class information-nameYou can write a class name.
Class information-base classIt must be derived from ccomtarget. Only ccomtarget provides idispatch support.
Automation-NoneIt indicates that automation is not supported. If you want to select it, you just need to do it.
Automation-AutomationAutomation is supported, but cannot be directly instantiated. I will use multiple idispatches later. Don't worry about it now.
Automation-createable by type IDYou must select this project. In this way, in the subsequent call, VB can Createobject (), and VC can instantiate the component object by createdispatch. Note that this ID is actually the progid of the component.
3-6: Start classwizard, select the automation card, and prepare to create a function.

3-7: Add a function. We need to write an integer addition function add ().

3-8: add the upper () function that converts the case of strings (). The Return Value of the function is BSTR. There is no doubt about this, but how is the parameter type actually lpctstr? Shouldn't a string use BSTR in com? Yes, we should use BSTR, but because we use MFC to write automation components, it helps us to convert between BSTR and lpctstr.

3-9: Okay. Enter the program code below:

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 and register
If an error occurs due to negligence, You can manually correct the error.
1. the dialog window in step <3-6> contains the "delete" operation;
2. You can open the odl file (note 2) to modify it. When modifying the file, you must be especially careful that there is a [ID (n)] function number in the function declaration;
3. Synchronously modify the function description and function body in H/CPP;
4. In the CPP file, modify begin_dispatch_map/end_dispatch_map () function to launch macros as needed.
After the correct compilation, the MFC will not automatically register as the ATL does. You need to manually execute regsvr32.exe for registration, or execute the menu "tools/register control"

4. implement dual interface components using ATL(For operation methods and steps, refer to COM Component Design and Application (v)
4-1: Create an ATL project named "simple6"
4-2: by default. Select the DLL type, do not merge proxy and stub code, do not support MFC, do not support MTS
4-3: new ATL object... select Simple Object
4-4: enter the name and attribute. The attribute is performed by default, that is, dual (dual Interface) mode (note 3)

4-5: Add a function. In the classview card, select the interface, right-click the menu, and 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) method. But this time we didn't use long, but used variant for parameters and return values. Here, I will first sell a theme. Let's look at the highlights of using variant.
4-6: complete the code

Stdmethodimp cdispsimple: add (variant V1, variant V2, variant * pval) {: variantinit (pval); // always initialize the returned value is a good habit of ccomvariant v_1 (V1 ); ccomvariant V_2 (V2); If (v1.vt & vt_i4) & (v2.vt & vt_i4) // if they are all integer types {// not used here =, the operator &, do you know why? V_1.changetype (vt_i4); // convert it to the integer v_2.changetype (vt_i4); // convert it to the integer pval-> VT = vt_i4; pval-> lval = v_1.lval + v_2.lval; // addition} else {v_1.changetype (vt_bstr); // convert it to the string v_2.changetype (vt_bstr); // convert it to the 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 returned value is a good habit of ccombstr S (STR); S. toupper (); // converts it to uppercase * pval = S. copy (); Return s_ OK ;}

I just sold the secret now ...... the addition function add () does not use the long type. The advantage of using variant is that the function dynamically judges the parameter type. If it is an integer, it performs an integer addition. If it is a string, then, the string is added (the string addition is the string connection ). That is to say, if the parameter is variant, we can implement the variable parameter type of the function. It's so cool!

5. Example of calling in script
Open the Notepad program, enter the script program, and save it as the XXX. vbs file. Then you can double-click it in the resource manager.

If you have the ability, you can also use JScript to write the above program and save it as a XXX. js file. You can also run it in the resource manager. Another point to note is that the icon in the script file (under Win 2000) is, if you are not like this (there is a software called "XX ". The developer level of the software is too low, and it is actually used. the extension file of vbs is used as its data stream file, which breaks the default file type shooting mode ......), you need to reset the settings:

6. Examples in Word
6-1: recording a macro Sequence


6-2: Select "keyboard". Of course, you can also put this "macro" program on the "toolbar. You can specify a shortcut, for example, CTRL + Z.

6-3: Start recording. You can enter something as needed. Click "stop"
6-4: Next, execute the menu, select the macro you just recorded, and edit it.

6-5: click "edit" and enter the following program:

If you have a little bit of VB, you can understand this stuff. Then save and close the VBA Editor (note 4 ).
6-6: Execute, execute, and see what the effect is ......
Press the shortcut key Ctrl + z
You have extended the MS word function La la ...... we just gave a simple example. In fact, this example has no practical significance, because word itself has the case-sensitive conversion function. However, through this small example, you can understand the functions of the automation components. Is it amazing ?!

VII. Summary
No summary! Hey hey :-)

Note 1: Later we will describe the interface functions in the IDL format.
Note 2: The odl file is similar to the IDL file and is an interface file specifically described for Automation by MFC.
Note 3: The dual interface is a special interface method that supports the idispatch interface. It will be discussed soon.
Note 4: VBA is a language dedicated to office development --- Visual Basic for application

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.