I. Preface
1. Ide: vc6.0 (ATL 3.0) Please read this article;
2. Except for the iunknown interfaces required by all COM components, the first component implements a self-defined interface ifun, which has two functions: add () completes the addition of two values, and CAT () completes the connection between the two strings.
2. Create an ATL Project
Step 2.1: Create a workspace ).
Step 2.2: Create an ATL Project in the workspace ). The sample program is simple1 and the DLL method is selected. See figure 1.
Figure 1. Create an atl dll Project
Dynamic link library (DLL)Build a DLL component program.
Executable (exe)Indicates creating an EXE component program.
Service (exe)Indicates the establishment of a service program, and the program will be loaded and executed after the system starts.
Allow merging of proxy/stub codeIf this option is selected, the "Proxy/stub" code is merged into the component program. Otherwise, you must compile the Code separately and register the proxy stub program separately. Proxy/stub. What is this concept? Do you remember what we introduced in the previous book? When the caller calls the functions of external or remote components, the proxy/stub is responsible for data exchange. Let's talk about the specific change and operation of proxy/stub ......
Support MFCUnless for a special reason, we should write the Atl program. It is best not to select this option. You may say that, without the support of MFC, what should you do with cstring? Let me tell you a secret. I don't tell anyone, so I will live with this secret for the rest of my life:
1. Do you know STL? It can be replaced by string in STL;
2. Write a mystring class by yourself;
3. quietly and secretly, do not tell others (especially don't tell Microsoft), and use the cstring source code in MFC;
4. Using the ccombstr class can at least simplify string operations;
5. directly use APIs to operate strings. When we all learn the C language, we start from here. (Not to mention, huh, huh)
Support MTSSupports transaction processing, that is, whether the COM + function is supported. COM + may be introduced back in 99th.
Iii. Add ATL object classes
Step 3.1: Choose Insert \ new ATL object... (or right-click to pop up the menu in the classview card), select the object category, and select the simple object project. See figure 2.
Figure 2. Select to create a simple COM Object
CATEGORY objectCommon components. There are many types of component objects that can be selected, but in essence, it is to let the wizard add some interfaces for us by default. For example, if we select "Simple Object", the wizard adds the iunknown interface to our components; if we select "Internet Explorer Object", the wizard adds the iunknown interface, add an iobjectwithsite interface for IE. Of course, we can add any interfaces manually.
CATEGORY controlsActiveX control. You can select many ActiveX types. We will discuss ActiveX programming later.
CATEGORY MiscellaneousAuxiliary miscellaneous components.
Categroy Data AccessDatabase components (I hate database programming, so I won't ).
Step 3.2: Add a custom cfun (interface ifun), as shown in figure 3.
Figure 3. Names of input classes
In fact, we only need to enter the short name (short name), and other projects will be automatically filled in. There is nothing to say, just pay attention to the progid item. The default progid construction method is "project name. Short name ".
Step 3.3: Fill in interface properties, as shown in figure 4.
Figure 4 interface attributes
Threading modelSelect the thread model supported by the component. Com thread, I think it is the most annoying and complex part. The concept of COM thread and apartment will be provided for further introduction. Now all of us choose apartment. What does it mean? Simply put, when a component function is called in a thread, these calls are queued. Therefore, in this mode, we do not need to consider synchronization for the moment.
InterfaceInterface basic type.Dual indicates that dual interfaces are supported.This is very important and very commonly used, but we will not talk about it today.Custom indicates a custom excuse.Remember! Remember! Our first
Com program, you must select it !!!!(If you have selected an error, delete all the content and try again .)
Aggregation: whether the components we write can be aggregated by others in the future. Only indicates that it must be aggregated before it can be used. It is similar to the pure virtual class in C ++. If you are a chief engineer, you can select it only for designing but not writing code yourself.
Support isupporterrorinfoWhether error handling interfaces with rich information are supported. I will talk about it later.
Support connection pointsWhether the connection point interface (event and callback) is supported ). I will talk about it later.
Free threaded already ALERI won't talk about it in the future. I won't talk about killing you!
4. Add interface functions
Figure 5. Call up the menu for adding an Interface Method
Figure 6. Add an interface function to the discussion group.
Figure 7. Add an interface function cat
Add the add () function strictly in the way shown in Figure 6. Since the parameter of the CAT () function added in Figure 7 is relatively long, I do not have proper spaces, please note when entering the information yourself.[In]Indicates that the parameter direction is input;[Out]Indicates that the parameter direction is output;[Out, retval]It indicates that the parameter direction is output and can be used as the return value of the function operation result. A function can have multiple [in] and [out], but [retval] can only have one, and it must be combined with [out] and placed in the last position.
Figure 8. Illustration after interface function definition
We all know that to change class functions in C ++, we need to modify two places: header file (. h) class function declaration. The second is the function body (. CPP) file implementation. Now, if we use ATL to write component programs, we need to modify the interface definition (IDL) file. Don't worry, IDL will discuss it next time.
Due to the bug in vc6.0, after adding interfaces and interface functions, you may not see the style shown in figure 8. Solution:
1. Close the project and re-open the method. This method is often valid. 2. Close the IDE and run it again. 3. Open the IDL file and check whether the interface function is correct. If not, modify it. 4. Open the IDL file, just modify it (add a space and then delete the space). Then, save this method and open the H/CPP file. Check whether the function exists or is correct, it's awkward not to say this idiom.
6. Delete the interface functions in IDL/h/CPP, and re-create the project, reinstall VC, reinstall windows, and smash the computer!
5. Implement interface functions
The cfun \ ifun \ add (...) in double-click graph 8 can start to input the function implementation:
Stdmethodimp cfun: add (long N1, long N2, long * pval) {* pval = N1 + N2; return s_ OK;} This is too simple, and it is no longer a waste of "Mouth ". Below we implement the CAT () function for string connection: stdmethodimp cfun: CAT (BSTR S1,
BSTR S2, BSTR * pval) {int nlen1 =: sysstringlen (S1); // the string length of S1 int nlen2 =: sysstringlen (S2 ); // S2 character length * pval =: sysallocstringlen (S1, nlen1 + nlen2); // construct a new BSTR and save S1 first if (nlen2 ){:: memcpy (* pval + nlen1, S2, nlen2 * sizeof (wchar)
); // Then connect S2 to/wcscat (* pval, S2);} return s_ OK;} Student: The above function implementation, this is done by calling the basic API.
Teacher: Yes. To be honest, it's really tricky.
Student: We use memcpy () to connect the second string. Why not use the wcscat () function?
INSTRUCTOR: it is acceptable in most cases, but you need to know that BSTR contains a string length, so the actual BSTR string content can store l'' \ 0, however, the wcscat () function uses l'' \ 0'' as the end mark of replication, which may cause data loss. Do you understand?
Student: understand, understand. After reading "Data Types of COM Component Design and Application", I will understand it. Is there any simple way, teacher?
Teacher: Yes, you see ...... stdmethodimp cfun: CAT (BSTR S1, BSTR S2, BSTR * pval) {ccombstr sresult (S1); sresult. appendbstr (S2); * pval = sresult. copy (); // * pval
= Sresult. Detach (); Return s_ OK;} Student: Haha, good! Using ccombstr is much simpler. What is the difference between ccombstr: Copy () and ccombstr: Detach?
INSTRUCTOR: ccombstr: Copy () will make a copy of BSTR. In addition, ccombstr: copyto () has similar functions. Ccombstr: Detach () is to strip the object from the internal BSTR pointer. This function is a little faster because there is no replication process. However, you must note that this object cannot be used once it is stripped.