?? ch13.htm
字號:
Classes and the Visual C++ AppWizard do much of the behind-the-scenes work for you.
The discussion in these chapters is just what you need to know to use COM as a developer.</P>
<P>COM is a binary standard for Windows objects. That means that the executable code
(in a DLL or EXE) that describes an object can be executed by other objects. Even
if two objects were written in different languages, they are able to interact using
the COM standard.</P>
<BLOCKQUOTE>
<P>
<HR>
<strong>NOTE:</strong> Because the code in a DLL executes in the same process as the calling
code, it's the fastest way for applications to communicate. When two separate applications
communicate through COM, function calls from one application to another must be <I>marshaled</I>:
COM gathers up all the parameters and invokes the function itself. A standalone server
(EXE) is therefore slower than an in-process server (DLL). 
<HR>
</BLOCKQUOTE>
<P>How do they interact? Through an <I>interface</I>. An ActiveX interface is a collection
of functions, or really just function names. It's a C++ class with no data, only
pure virtual functions. Your objects inherit from this class and provide code for
the functions. (Remember, as discussed in Appendix A, "C++ Review and Object-Oriented
Concepts," a class that inherits a pure virtual function doesn't inherit code
for that function.) Other programs get to your code by calling these functions. All
ActiveX objects must have an interface named IUnknown (and most have many more, all
with names that start with I, the prefix for interfaces).</P>
<P>The IUnknown interface has only one purpose: finding other interfaces. It has
a function called QueryInterface() that takes an interface ID and returns a pointer
to that interface for this object. All the other interfaces inherit from IUnknown,
so they have a QueryInterface() too, and you have to write the code--or you would
if there was no MFC. MFC implements a number of macros that simplify the job of writing
interfaces and their functions, as you will shortly see. The full declaration of
IUnknown is in Listing 13.1. The macros take care of some of the work of declaring
an interface and won't be discussed here. There are three functions declared: QueryInterface(),
AddRef(), and Release(). These latter two functions are used to keep track of which
applications are using an interface. All three functions are inherited by all interfaces
and must be implemented by the developer of the interface.</P>
<P>
<H4>Listing 13.1  IUnknown, Defined in \Program Files\Microsoft Visual
Studio\VC98\Include\unknwn.h</H4>
<PRE>MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
IUnknown
{
public:
BEGIN_INTERFACE
virtual HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) = 0;
virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;
virtual ULONG STDMETHODCALLTYPE Release( void) = 0;
#if (_MSC_VER >= 1200) // VC6 or greater
template <class Q>
HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)
{
return QueryInterface(__uuidof(Q), (void**)pp);
}
#endif
END_INTERFACE
</PRE>
<PRE> };
</PRE>
<H2><A NAME="Heading7"></A>Automation</H2>
<P>An Automation server lets other applications tell it what to do. It <I>exposes</I>
functions and data, called <I>methods</I> and <I>properties</I>. For example, Microsoft
Excel is an Automation server, and programs written in Visual C++ or Visual Basic
can call Excel functions and set properties like column widths. That means you don't
need to write a scripting language for your application any more. If you expose all
the functions and properties of your application, any programming language that can
control an Automation server can be a scripting language for your application. Your
users may already know your scripting language. They essentially will have no learning
curve for writing macros to automate your application (although they will need to
learn the names of the methods and properties you expose).</P>
<P>The important thing to know about interacting with automation is that one program
is always in control, calling the methods or changing the properties of the other
running application. The application in control is called an Automation controller.
The application that exposes methods and functions is called an Automation server.
Excel, Word, and other members of the Microsoft Office suite are Automation servers,
and your programs can use the functions of these applications to really save you
coding time.</P>
<P>For example, imagine being able to use the function called by the Word menu item
Format, Change Case to convert the blocks of text your application uses to all uppercase,
all lowercase, sentence case (the first letter of the first word in each sentence
is uppercase, the rest are not), or title case (the first letter of every word is
uppercase; the rest are not).</P>
<P>The description of how automation really works is far longer and more complex
than the interface summary of the previous section. It involves a special interface
called IDispatch, a simplified interface that works from a number of different languages,
including those like Visual Basic that can't use pointers. The declaration of IDispatch
is shown in Listing 13.2.</P>
<P>
<H4>Listing 13.2  IDispatch, Defined in \Program Files\Microsoft Visual
Studio\VC98\Include\oaidl.h</H4>
<PRE>MIDL_INTERFACE("00020400-0000-0000-C000-000000000046")
IDispatch : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
/* [out] */ UINT __RPC_FAR *pctinfo) = 0;
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) = 0;
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId) = 0;
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
/* [out] */ VARIANT __RPC_FAR *pVarResult,
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr) = 0;
</PRE>
<PRE> };
</PRE>
<P>Although IDispatch seems more complex than IUnknown, it declares only a few more
functions: GetTypeInfoCount(), GetTypeInfo(), GetIDsOfNames(), and Invoke(). Because
it inherits from IUnknown, it has also inherited QueryInterface(), AddRef(), and
Release(). They are all pure virtual functions, so any COM class that inherits from
IDispatch must implement these functions. The most important of these is Invoke(),
used to call functions of the Automation server and to access its properties.</P>
<P>
<H2><A NAME="Heading8"></A>ActiveX Controls</H2>
<P>ActiveX controls are tiny little Automation servers that load <I>in process</I>.
This means they are remarkably fast. They were originally called OLE Custom Controls
and were designed to replace VBX controls, 16-bit controls written for use in Visual
Basic and Visual C++. (There are a number of good technical reasons why the VBX technology
could not be extended to the 32-bit world.) Because OLE Custom Controls were traditionally
kept in files with the extension .OCX, many people referred to an OLE Custom Control
as an OCX control or just an OCX. Although the OLE has been supplanted by ActiveX,
ActiveX controls produced by Visual C++ 6.0 are still kept in files with the .OCX
extension.</P>
<P>The original purpose of VBX controls was to allow programmers to provide unusual
interface controls to their users. Controls that looked like gas gauges or volume
knobs became easy to develop. But almost immediately, VBX programmers moved beyond
simple controls to modules that involved significant amounts of calculation and processing.
In the same way, many ActiveX controls are far more than just controls; they are
<I>components</I> that can be used to build powerful applications quickly and easily.</P>
<BLOCKQUOTE>
<P>
<HR>
<strong>NOTE:</strong> If you have built an OCX in earlier versions of Visual C++, you might
think it is a difficult thing to do. The Control Developer Kit, now integrated into
Visual C++, takes care of the ActiveX aspects of the job and allows you to concentrate
on the calculations, display, or whatever else it is that makes your control worth
using. The ActiveX Control Wizard makes getting started with an empty ActiveX control
simple.
<HR>
</BLOCKQUOTE>
<P>Because controls are little Automation servers, they need to be used by an Automation
controller, but the terminology is too confusing if there are controls and controllers,
so we say that ActiveX controls are used by <I>container</I> applications. Visual
C++ and Visual Basic are both container applications, as are many members of the
Office suite and many non-Microsoft products.</P>
<P>In addition to properties and methods, ActiveX controls have <I>events</I>. To
be specific, a control is said to <I>fire</I> an event, and it does so when there
is something that the container needs to be aware of. For example, when the user
clicks a portion of the control, the control deals with it, perhaps changing its
appearance or making a calculation, but it may also need to pass on word of that
click to the container application so that a file can be opened or some other container
action can be performed.</P>
<P>This chapter has given you a brief tour through the concepts and terminology used
in ActiveX technology, and a glimpse of the power you can add to your applications
by incorporating ActiveX into them. The remainder of the chapters in this part lead
you through the creation of ActiveX applications, using MFC and the wizards in Visual
C++.</P>
<H1></H1>
<CENTER>
<P>
<HR>
<A HREF="../ch12/ch12.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch14/ch14.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
<BR>
</P>
<P>© <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>
</BODY>
</HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -