⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch04.htm

📁 本书详述了VC++环境下网络化多媒体对象技术编程
💻 HTM
📖 第 1 页 / 共 5 页
字号:
on the other types of objects that can be created. Click the <U>N</U>ext button to
continue. <A HREF="art/04/dfig04.jpg"><B><BR>
<BR>
FIG. 4.4</B></A> <I><BR>
Select the type of ATL object to add to your project.</I></P>
<P>The next dialog is the ATL Object Wizard Properties dialog, which is used to define
the specific properties of the new object that will be added to your project. Select
the Names tab (see fig. 4.5), and in the <U>S</U>hort Name edit field, type Tracker;
the remainder of the edit fields will automatically update, reflecting the short
name that you added. The other fields can be changed, but in this case, you will
use the default values.<BR>
<BR>
 <A HREF="art/04/dfig05.jpg"><B>FIG. 4.5</B></A> <I><BR>
Define the name of the new control object.</I></P>
<P>Select the Attributes tab so that you can define the attributes of the server
object (see fig. 4.6). Check the Support <U>I</U>SupportErrorInfo check box to add
OLE rich error. You can add events to the ATL object by checking the Support Connection
Points check box; however, for the purposes of the sample, you will not. Leave the
remainder of the settings on the Attributes tab at their default values. Click OK
to continue and to add the object to the project. <A HREF="art/04/dfig06.jpg"><B><BR>
<BR>
FIG. 4.6</B></A> <I><BR>
Define the attributes of the new server object.</I></P>
<P><A HREF="ch08.htm">Chapters 8</A> and <A HREF="ch09.htm">9</A> go into detail
about adding events to an ATL control; the same process is used for an ATL server.
At the time this book was being written, one drawback to having events was that only
VB5 was built to take advantage of them.</P>
<P>The ATL ObjectWizard added the files, Tracker.h, Tracker.cpp, and Tracker.rgs
to the project. Tracker.h and Tracker.cpp are the implementation files for your server
object. Tracker.rgs is the registry script file that is used to register your server
in the registration database. You will learn more about the Tracker.rgs file in the
section regarding server registration a little later in this chapter.</P>
<P>Before continuing with your server implementation, your newly created IDL file
deserves a quick review. Listing 4.1 shows the basic IDL file that is generated by
the AppWizard. <BR>
<BR>
<IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"></P>


<BLOCKQUOTE>
	<P><B>TIP:</B> For clarity, you should add the <TT>hidden</TT> attribute to the <TT>IDispatch</TT>-based
	interfaces defined in the server (see Listing 4.1). This step prevents tools like
	VB from displaying both the <TT>IDispatch</TT> interface and its related <TT>CoClass</TT>
	within the VB Object browser. The <TT>CoClass</TT> is the only interface that needs
	to be visible since it is the only interface that VB uses. Using the <TT>IDispatch</TT>
	interface in VB will result in errors.

</BLOCKQUOTE>

<P><IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"> <BR>
<BR>
The most obvious difference between the ODL from the MFC sample and the IDL of this
sample is the location of the <TT>IDispatch</TT> interface relative to the rest of
the <I>type library</I> description. When using IDL, you must declare the interfaces
that will generate the C++ source files outside of the library declaration. For the
ODL, this step is not necessary. Other than a few minor language differences, the
IDL and ODL are identical in terms of syntax and organization.
<H3><A NAME="Heading4"></A>Listing 4.1 ATLSERVER.IDL--IDL File for the ATL Server
Sample</H3>
<P><FONT COLOR="#0066FF"><TT>import &quot;oaidl.idl&quot;; <BR>
// ATLServer.idl : IDL source for ATLServer.dll <BR>
// // This file will be processed by the MIDL tool to <BR>
// produce the type library (ATLServer.tlb) and marshalling code. [ <BR>
object, <BR>
uuid(03699612-809E-11D0-BEFF-00400538977D), <BR>
dual, <BR>
helpstring(&quot;ITracker Interface&quot;), <BR>
pointer_default(unique), <BR>
hidden <BR>
] <BR>
interface ITracker : IDispatch <BR>
{ <BR>
}; <BR>
[ <BR>
uuid(03699601-809E-11D0-BEFF-00400538977D), <BR>
version(1.0), <BR>
helpstring(&quot;ATLServer 1.0 Type Library&quot;) <BR>
] <BR>
library ATLSERVERLib <BR>
{ <BR>
importlib(&quot;stdole32.tlb&quot;); [ <BR>
uuid(03699613-809E-11D0-BEFF-00400538977D), <BR>
helpstring(&quot;Tracker Class&quot;) <BR>
] <BR>
coclass Tracker <BR>
{ <BR>
[default] interface ITracker; <BR>
}; }; </TT></FONT></P>
<P>Before another application can use the server, however, OLE has to know where
to find the server, which is done through the system registry. All ActiveX components
that are publicly available to other applications must support registration and must
create valid registry entries.
<H2><A NAME="Heading5"></A>Registry</H2>
<P>ActiveX components have one or more registry entries that are used to describe
various aspects of the application and how it can be used. The registry is critical
to the successful launching and using of ActiveX components.</P>
<P>All inproc ActiveX components expose registration support via two exported functions:
<TT>DllRegisterServer</TT> and <TT>DllUnregisterServer</TT>. For information regarding
the registration of local servers, see <A HREF="ch03.htm">Chapter 3</A>.</P>
<P>The basic registration and unregistration support for the server is already implemented
by ATL. You are not required to make code changes or additions to support it. Remember
that the MFC implementation allows only for registering the server and does not support
unregistration.</P>
<P>Unlike MFC which uses a set of constants, ATL relies on resource information in
the form of a registry script file to define the information that is added to the
registry database. The registry script file is added automatically to the project
when the server object is added; there is one script file for each server object.</P>
<P>The registry script file(s) are compiled into the server project as resources
and can be viewed in binary form in the resource editor. The files, which have the
extension .rgs, are normal text files that can be edited within the IDE. For more
information about the use of registry script files and their particular syntax, see
the VC++ books online subject &quot;Registry Scripting Examples--ActiveX Template
Library, Articles.&quot; Listing 4.2 shows the registry script file for the <TT>CTracker</TT>
server object that you added.
<H3><A NAME="Heading6"></A>Listing 4.2 ATLCONTROLWIN.RGS--Sample Registry Script
File for the CTracker Server Object<FONT COLOR="#0066FF"><TT></TT></FONT></H3>
<P><FONT COLOR="#0066FF"><TT>HKCR <BR>
{ <BR>
Tracker.Tracker.1 = s `Tracker Class' <BR>
{ <BR>
CLSID = s `{03699613-809E-11D0-BEFF-00400538977D}' <BR>
} <BR>
Tracker.Tracker = s `Tracker Class' <BR>
{ <BR>
CurVer = s `Tracker.Tracker.1' <BR>
} <BR>
NoRemove CLSID <BR>
{ <BR>
ForceRemove {03699613-809E-11D0-BEFF-00400538977D} = s `Tracker Class' <BR>
{ <BR>
ProgID = s `Tracker.Tracker.1' <BR>
VersionIndependentProgID = s `Tracker.Tracker' <BR>
ForceRemove `Programmable' <BR>
LocalServer32 = s `%MODULE%' <BR>
} <BR>
} <BR>
} </TT></FONT></P>

<P><IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"></P>


<BLOCKQUOTE>
	<P><B>NOTE:</B> Unfortunately, at the time of the writing of this book, the ATL ClassWizard
	created the Tracker.rgs file incorrectly. Hopefully, this problem will be fixed by
	the time the product is released. Listing 4.3 shows the updated version of the Tracker.rgs
	file with the mistakes corrected. The first correction was to change the <TT>ProgID</TT>
	to <TT>ATLServer.Tracker</TT>, reflecting the parent module and the subordinate object.
	The next correction was to add the <TT>CLSID</TT> entry to the version- independent
	<TT>ProgID</TT> section. This may have been intentional on the part of the ATL team.
	The last and definitely most significant problem was the fact that the <TT>CLSID</TT>
	section listed the server as <TT>LocalServer32</TT> and not <TT>InprocServer32</TT>.
	After making the corrections, the server registered and ran as expected.

</BLOCKQUOTE>

<P><IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0">
<H3><A NAME="Heading8"></A>Listing 4.3 TRACKER.RGS--Updated Tracker.rgs File</H3>
<P><FONT COLOR="#0066FF"><TT>HKCR <BR>
{ <BR>
ATLServer.Tracker.1 = s `Tracker Class' <BR>
{ <BR>
CLSID = s `{03699613-809E-11D0-BEFF-00400538977D}' <BR>
} <BR>
ATLServer.Tracker = s `Tracker Class' <BR>
{ <BR>
CLSID = s `{03699613-809E-11D0-BEFF-00400538977D}' <BR>
CurVer = s `ATLServer.Tracker.1' <BR>
} <BR>
NoRemove CLSID <BR>
{ <BR>
ForceRemove {03699613-809E-11D0-BEFF-00400538977D} = s `Tracker <BR>
{ <BR>
ProgID = s `ATLServer.Tracker.1' <BR>
VersionIndependentProgID = s `ATLServer.Tracker' <BR>
ForceRemove `Programmable' <BR>
InprocServer32 = s `%MODULE%' <BR>
} <BR>
} } </TT></FONT></P>
<H2><A NAME="Heading9"></A>Sample Server Support Code</H2>
<P>Since the server is used to output data to a file, you first need to add some
support code to the application before adding its methods and properties.</P>
<P>Listing 4.4 shows the changes and additions that need to be made to the class
header file. First add a destructor to the class and remove the constructor implementation--you
will add it to the source file later. Then add a set of member variables for storing
the file handle and timer information that will be used throughout the server implementation.
<H3><A NAME="Heading10"></A>Listing 4.4 Tracker.H--Sample Server Support Code Added
to the Tracker Header File</H3>
<P><FONT COLOR="#0066FF"><TT>/////////////////////////////////////////////////////////////////////////////
<BR>
// CTracker <BR>
class ATL_NO_VTABLE CTracker : <BR>
public CComObjectRootEx&lt;CComObjectThreadModel&gt;, <BR>
public CComCoClass&lt;CTracker, &amp;CLSID_Tracker&gt;, <BR>
public ISupportErrorInfo, <BR>
public IDispatchImpl&lt;ITracker, &amp;IID_ITracker, &amp;LIBID_ATLSERVERLib&gt;
<BR>
{ <BR>
public: <BR>
// constructor <BR>
CTracker(); <BR>
// destructor <BR>
~CTracker(); DECLARE_REGISTRY_RESOURCEID(IDR_TRACKER) BEGIN_COM_MAP(CTracker) <BR>
COM_INTERFACE_ENTRY(ITracker) <BR>
COM_INTERFACE_ENTRY(IDispatch) <BR>
COM_INTERFACE_ENTRY(ISupportErrorInfo) <BR>
END_COM_MAP() // ISupportsErrorInfo <BR>
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid); // ITracker <BR>
public: protected: <BR>
FILE * m_fileLog; <BR>
long m_lTimeBegin; <BR>
long m_lHiResTime; <BR>
long m_lLastHiResTime; }; </TT></FONT></P>

<P>The next step is to update the source file for the class. Add the include file,
mmsystem.h, before the Tracker.h include file (see Listing 4.5). This file is for
the timer functions that you take advantage of throughout the server implementation.</P>

<P>The following line is added within the constructor:</P>
<P><FONT COLOR="#0066FF"><TT><BR>
AFX_MANAGE_STATE(AfxGetStaticModuleState()); </TT></FONT></P>
<P>If you are using MFC with ATL, you must add this line as the first line in every
function that uses MFC. This line is needed to stabilize the state information that
is used by MFC. If you do not perform this step, the server will not function correctly
and can result in errors during program execution.</P>
<P>You must call the method <TT>AfxOleLockApp()</TT> to ensure that the application
will not be unloaded from memory until the reference count reaches zero.</P>
<P>Next you create a high resolution timer and store its current value in your member
variables. The timer is useful for determining the number of milliseconds that have
passed since the last method call was made. The timer output is great for tracking
the performance of a particular action or set of actions.</P>
<P>You then get the current date and create a filename with the format YYYYMMDD.tracklog.
After successfully opening the file, you output some start-up data to the file and
exit the constructor.</P>
<P>The destructor does the exact opposite of the constructor. If there is a valid
file handle, you write some closing information to the file and close it. Next you
terminate the timer. Remember to call the function <TT>AfxOleUnlockApp()</TT> to
allow the application to be removed from memory.
<H3><A NAME="Heading12"></A>Listing 4.5 TRACKER.CPP--Sample Server Support Code Added
to the Source File</H3>
<P><FONT COLOR="#0066FF"><TT><BR>
// Tracker.cpp : Implementation of CTracker <BR>
#include &quot;stdafx.h&quot; <BR>
#include &quot;ATLServer.h&quot; <BR>
// needed for the high resolution timer services <BR>
#include &lt;mmsystem.h&gt; <BR>
#include &quot;Tracker.h&quot; /////////////////////////////////////////////////////////////////////////////
<BR>
// CTracker STDMETHODIMP CTracker::InterfaceSupportsErrorInfo(REFIID riid) <BR>
{ <BR>
static const IID* arr[] = <BR>
{ <BR>
&amp;IID_ITracker, <BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -