COM Component Design and Application (10)

Source: Internet
Author: User

COM Component Design and Application (10)
Idispatch interface for vc.net

Author: Instructor Yang

Download source code

I. Preface
I finally wrote the tenth time, and I have been hoping to write this time. 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, read the previous one.
If you use vc.net 2003, continue ......

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 solution
3-2: Create an mfc dll project named "simple7"

3-3: Be sure to select "Automation" in the additional functions. Remember! Remember!

3-4: Add a new class

3-5: supports automation in the new class

Class NameYou can write a class name.
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-creation 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: Select an interface and add 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 ().

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

LONG CDispSimple::Add(LONG n1, LONG n2){AFX_MANAGE_STATE(AfxGetStaticModuleState());return n1 + n2;}BSTR CDispSimple::Upper(LPCTSTR str){AFX_MANAGE_STATE(AfxGetStaticModuleState());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. You can open the IDL file to modify the function. When modifying the function, be careful that there is a [ID (n)] function serial number in the function declaration;
2. Synchronously modify the function description and function body in H/CPP;
3. In the CPP file, modify begin_dispatch_map/end_dispatch_map () function to launch a macro as needed.
After correct compilation, vc.net 2003 is much smarter than vc6.0, and it automatically registers components. If you want to copy data to another computer, you also need to manually execute regsvr32.exe for registration.

4. implement dual interface components using ATL(For operation methods and steps, refer to COM Component Design and Application (6)
4-1: Create an ATL project named "simple8"
4-2: select the DLL type, non-attribute mode, and do not select any additional options
4-3: Add a new class and select a simple object of ATL
4-4: Enter the abbreviation and option. The option is implemented by default, that is, the dual interface method (note 2)

4-5: Add a function. Select Interface, right-click 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) 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 dual interface is a special interface method that supports the idispatch interface. It will be discussed soon.
NOTE 3: 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.