Programming with Microsoft Visual C++.NET 6ed [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming with Microsoft Visual C++.NET 6ed [Electronic resources] - نسخه متنی

George Shepherd, David Kruglinski

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید








Automation Programming Choices


Suppose you're writing an Automation component in C++. You've got some choices to make. Do you want an in-process component or an out-of-process component? What kind of user interface do you want? Does the component need a user interface at all? Can users run your EXE component as a standalone application? If the component is an EXE, will it be Single Document Interface (SDI) or Multiple Document Interface (MDI)? Can the user shut down the component program directly?

If your component is a DLL, COM linkage will be more efficient than it would be with an EXE component because no marshaling is required. Most of the time, your in-process Automation components won't have their own user interfaces, except for modal dialog boxes. If you need a component that manages its own child window, you should use an ActiveX control, and if you want to use a main frame window, you should use an out-of-process component. As with any 32-bit DLL, an Automation DLL is mapped into the client's process memory. If two client programs happen to request the same DLL, Windows will load and link the DLL twice. Each client will be unaware that the other is using the same component.

With an EXE component, however, you must be careful to distinguish between a component program and a component object. When a client calls IClassFactory::CreateInstance to construct a component object, the component's class factory constructs the object, but COM might or might not need to start the component program.

Here are some scenarios:



    The component's COM-creatable class is programmed to require a new process for each object constructed. In this case, COM starts a new process in response to the second and subsequent CreateInstance calls, each of which returns an IDispatch pointer.



    Here's a special case of the above scenario that's specific to MFC applications. The component class is an MFC document class in an SDI application. Each time a client calls CreateInstance, a new component process starts, complete with a document object, a view object, and an SDI main frame window.



    The component class is programmed to allow multiple objects in a single process. Each time a client calls CreateInstance, a new component object is constructed. There is only one component process, however.



    Here's a special case of the above scenario that's specific to MFC applications. The component class is an MFC document class in an MDI application. There is a single component process with one MDI main frame window. Each time a client calls CreateInstance, a new document object is constructed, along with a view object and an MDI child frame window.



There's one more interesting case. Suppose a component EXE is running before the client needs it, and then the client decides to access a component object that already exists. You'll see this case with Excel. The user might have Excel running but minimized on the desktop, and the client might need access to Excel's one and only Application object. The client will call the COM function GetActiveObject, which provides an interface pointer for an existing component object. If the call fails, the client can create the object with CoCreateInstance.

For component object deletion, normal COM rules apply. Automation objects have reference counts, and they delete themselves when the client calls Release and the reference count goes to 0. In an MDI component, if the Automation object is an MFC document, its destruction will cause the corresponding MDI child window to close. In an SDI component, the destruction of the document object will cause the component process to exit. The client is responsible for calling Release for each IDispatch interface before the client exits. For EXE components, COM will intervene if the client exits without releasing an interface, thus allowing the component process to exit. You can't always depend on this intervention, however, so be sure that your client cleans up its interfaces!

With generic COM, a client application often obtains multiple interface pointers for a single component object. Look back at the spaceship example in Chapter 22, in which the simulated COM component class has both an IMotion pointer and an IVisual pointer. With Automation, however, there's usually only a single (IDispatch) pointer per object. As in all COM programming, you must be careful to release all your interface pointers. In Excel, for example, many properties return an IDispatch pointer to new or existing objects. If you fail to release a pointer to an in-process COM component, the Debug version of the MFC library will alert you with a memory-leak dump when the client program exits.


The MFC IDispatch Implementation


The component program can implement its IDispatch interface in several ways. The most common way passes off much of the work to the Windows COM DLLs by calling the COM function CreateStdDispatch or by delegating the Invoke call to the ITypeInfo interface, which involves the component's type library. A type library is a table, locatable through the Registry that allows a client to query the component for the symbolic names of objects, methods, and properties. A client can, for example, contain a browser that allows the user to explore the component's capabilities.

The MFC library supports type libraries, but it doesn't use them in its implementation of IDispatch, which is instead driven by a dispatch map. MFC programs don't call CreateStdDispatch at all, nor do they use a type library to implement IDispatch::GetIDsOfNames. This means you can't use the MFC library if you implement a multilingual Automation component—one that supports English and German property and method names, for example. (CreateStdDispatch doesn't support multilingual components either.)

Later in this chapter, you'll learn how a client can use a type library, and you'll see how MFC wizards create and maintain type libraries for you. Once your component has a type library, a client can use it for browsing, independent of the IDispatch implementation.



/ 319