📄 ch09.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!--last modified on Tue, Apr 15, 1997 10:57 AM-->
<HTML>
<HEAD>
<!-- This document was created from RTF source by rtftohtml version 3.0.1 -->
<META NAME="GENERATOR" Content="Symantec Visual Page 1.0">
<META NAME="Author" Content="Steph Mineart">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<TITLE>Chapter 9</TITLE>
</HEAD>
<BODY BACKGROUND="../images/r2harch.gif" TEXT="#000000" BGCOLOR="#FFFFFF">
<H1>Chapter 9<BR>
Advanced ActiveX Control Development with ATL</H1>
<UL>
<LI><A HREF="#Heading1">Advanced ActiveX Control Development with ATL</A>
<UL>
<LI><A HREF="#Heading2">Properties</A>
<UL>
<LI><A HREF="#Heading3">Creating Asynchronous Properties</A>
<LI><A HREF="#Heading4">Listing 9.1 ATLCONTROL.IDL--Change the dispid of the ReadyState
Property to the Stock Property dispid--DISPID_READYSTATE</A>
<LI><A HREF="#Heading5">Listing 9.2 ATLCONTROLWIN.H--Add the m_lReadyState Member
to the CATLControlWin Class</A>
<LI><A HREF="#Heading6">Listing 9.3 ATLCONTROLWIN.H--Initialize the m_lReadyState
Member Variable in the Class Constructor</A>
<LI><A HREF="#Heading7">Listing 9.4 ATLCONTROLWIN.CPP--Implement the get_ReadyState
Function to Return the Current ReadyState Value</A>
<LI><A HREF="#Heading8">Listing 9.5 ATLCONTROL.IDL--Add the ReadyStateChange Event
to the IDL File</A>
<LI><A HREF="#Heading9">Listing 9.6 ATLCONTROL.IDL--Add the dispidTextDataPath Enumeration
to the IDL File</A>
<LI><A HREF="#Heading10">Listing 9.7 ATLCONTROLWIN.H--The m_bstrTextDataPath Member
Variable Is Added to the Class Declaration to Store the TextDataPath Property</A>
<LI><A HREF="#Heading11">Listing 9.8 ATLCONTROLWIN.CPP--Implementation of the get_TextDataPath
/put_TextDataPath Functions</A>
<LI><A HREF="#Heading12">Listing 9.9 ATLCONTROLWIN.CPP--OnData Function Implementation</A>
<LI><A HREF="#Heading13">Listing 9.10 ATLCONTROLWIN.H--TextDataPath Member Added
to the Property Persistence Macro</A>
<LI><A HREF="#Heading14">Static and Dynamic Property Enumeration</A>
<LI><A HREF="#Heading15">Listing 9.11 ATLCONTROLWIN.H--IPerPropertyBrowsing Interface
Function Prototypes Must Be Added to the Class Declaration</A>
<LI><A HREF="#Heading16">Listing 9.12 ATLCONTROLWIN.CPP--MapPropertyToPage Implementation</A>
<LI><A HREF="#Heading17">Listing 9.13 ATLCONTROLWIN.CPP--GetPredefinedStrings Implementation</A>
<LI><A HREF="#Heading18">Listing 9.14 ATLCONTROLWIN.CPP--GetPredefinedValue Implementation</A>
<LI><A HREF="#Heading19">Listing 9.15 ATLCONTROLWIN.CPP--GetDisplayString Implementation</A>
</UL>
<LI><A HREF="#Heading20">Drawing the Control</A>
<UL>
<LI><A HREF="#Heading21">Optimized Drawing</A>
<LI><A HREF="#Heading22">Listing 9.16 ATLCONTROLWIN.H--Drawing Implementation Member
Variables and Functions</A>
<LI><A HREF="#Heading23">Listing 9.17 ATLCONTROLWIN.CPP--OnDestroy Implementation
of Drawing Resource Cleanup</A>
<LI><A HREF="#Heading24">Listing 9.18 ATLCONTROLWIN.CPP--OnDraw Function Updated
to Support Optimized Drawing</A>
</UL>
<LI><A HREF="#Heading25">Adding Clipboard and Drag and Drop Support</A>
<UL>
<LI><A HREF="#Heading26">Clipboard Support</A>
<LI><A HREF="#Heading27">Listing 9.19 ATLCONTROLWIN.H--WM_KEYDOWN and OnKeyDown Message
Handler Added to the Class Declaration of the Control</A>
<LI><A HREF="#Heading28">Listing 9.20 ATLCONTROLWIN.CPP--OnKeyDown Implementation</A>
<LI><A HREF="#Heading29">Listing 9.21 ATLCONTROLWIN.H--Helper Functions and Member
Variables for Clipboard Support</A>
<LI><A HREF="#Heading30">Listing 9.22 ATLCONTROLWIN.H--IEnumFORMATETC Interface Added
to theClass Inheritance Hierarchy</A>
<LI><A HREF="#Heading31">Listing 9.23 ATLCONTROLWIN.H--Member Initialization in the
Class Constructor</A>
<LI><A HREF="#Heading32">Listing 9.24 ATLCONTROLWIN.CPP--CopyDataToClipboard Helper
Function Implementation</A>
<LI><A HREF="#Heading33">Listing 9.25 ATLCONTROLWIN.CPP--PrepareDataForTransfer Helper
Function Implementation</A>
<LI><A HREF="#Heading34">Listing 9.26 ATLCONTROLWIN.CPP--CopyStgMedium Helper Function
Implementation</A>
<LI><A HREF="#Heading35">Listing 9.27 ATLCONTROLWIN.CPP--IDataObject Interface Implementation</A>
<LI><A HREF="#Heading36">Listing 9.28 ATLCONTROLWIN.CPP--IEnumFORMATETC Interface
Implementation</A>
<LI><A HREF="#Heading37">Listing 9.29 ATLCONTROLWIN.H--Clipboard Target Support Helper
Function Prototypes</A>
<LI><A HREF="#Heading38">Listing 9.30 MFCCONTROLWINCTL.CPP--GetDataFromClipboard
Implementation</A>
<LI><A HREF="#Heading39">Listing 9.31 MFCCONTROLWINCTL.CPP--GetDataFromTransfer Implementation</A>
<LI><A HREF="#Heading40">Listing 9.32 ATLCONTROLWIN.CPP--OnKeyDown Implementation</A>
<LI><A HREF="#Heading41">Drag and Drop Support</A>
<LI><A HREF="#Heading42">Listing 9.33 ATLCONTROLWIN.H--IDropSource Interface Added
to the CATLControlWin Class Declaration</A>
<LI><A HREF="#Heading43">Listing 9.34 ATLCONTROLWIN.H--WM_LBUTTONDOWN and OnLButtonDown
Message Handler Added to the Class Declaration of the Control</A>
<LI><A HREF="#Heading44">Listing 9.35 ATLCONTROLWIN.CPP--OnLButtonDown Implementation</A>
<LI><A HREF="#Heading45">Listing 9.36 ATLCONTROLWIN.CPP--IDropSource Implementation</A>
<LI><A HREF="#Heading46">Listing 9.37 ATLCONTROLWIN.H--IDropTarget Interface Added
to the CATLControlWin Class Declaration</A>
<LI><A HREF="#Heading47">Listing 9.38 ATLCONTROLWIN.H--WM_CREATE Message Handler</A>
<LI><A HREF="#Heading48">Listing 9.39 ATLCONTROLWIN.CPP--OnCreate Implementation</A>
<LI><A HREF="#Heading49">Listing 9.40 ATLCONTROLWIN.CPP--OnDestroy Implementation
Updated to Revoke the Control as a Valid Drop Target</A>
<LI><A HREF="#Heading50">Listing 9.41 ATLCONTROLWIN.CPP--IDropTarget Interface Implementation</A>
<LI><A HREF="#Heading51">Custom Clipboard and Drag and Drop Formats</A>
<LI><A HREF="#Heading52">Listing 9.42 ATLCONTROLWIN.H--Custom Data Format Member
Variables</A>
<LI><A HREF="#Heading53">Listing 9.43 ATLCONTROLWIN.H--Register the Custom Format
and Initialize the Member Variables in the Class Constructor</A>
<LI><A HREF="#Heading54">Listing 9.44 ATLCONTROLWIN.CPP--PrepareDataForTransfer Update</A>
<LI><A HREF="#Heading55">Listing 9.45 ATLCONTROLWIN.CPP--GetDataFromTransfer Update</A>
<LI><A HREF="#Heading56">Listing 9.46 ATLCONTROLWIN.CPP--IEnumFORMATETC::Next Update</A>
<LI><A HREF="#Heading57">Listing 9.47 TLCONTROLWIN.CPP--IEnumFORMATETC::GetData Update</A>
</UL>
<LI><A HREF="#Heading58">Subclassing Existing Windows Controls</A>
<UL>
<LI><A HREF="#Heading59">Listing 9.48 ATLCONTROLSUBWIN.H--CATLControlSubWin Class
Implementation</A>
</UL>
<LI><A HREF="#Heading60">Dual-Interface Controls</A>
<LI><A HREF="#Heading61">Other ActiveX Features</A>
<UL>
<LI><A HREF="#Heading62">Windowless Activation</A>
<LI><A HREF="#Heading63">Flicker-Free Activation</A>
<LI><A HREF="#Heading64">Mouse Pointer Notifications When Inactive</A>
<LI><A HREF="#Heading65">Optimized Drawing Code</A>
<LI><A HREF="#Heading66">Loads Properties Asynchronously</A>
</UL>
<LI><A HREF="#Heading67">From Here...</A>
</UL>
</UL>
<P>
<HR SIZE="4">
<H1><A NAME="Heading1"></A>Advanced ActiveX Control Development with ATL</H1>
<UL>
<LI><B>Asynchronous properties</B>
<SPACER TYPE="VERTICAL" SIZE="2">
ATL hides some of the implementation details making implementation easier.
<P>
<LI><B> Property enumeratio</B>
<SPACER TYPE="VERTICAL" SIZE="2">
Property enumeration allows you to restrict the set of values a property can contain
and makes the property appear more professional in its implementation.
<P>
<LI><B>Optimized drawing</B>
<SPACER TYPE="VERTICAL" SIZE="2">
Optimized drawing with ATL is easy and can have positive effects on the performance
and appearance of the control.
<P>
<LI><B>Clipboard and Drag and Drop</B>
<SPACER TYPE="VERTICAL" SIZE="2">
With ATL, you can use a set of routines that includes support for custom data types.
<P>
<LI><B>Subclassing Windows controls</B>
<SPACER TYPE="VERTICAL" SIZE="2">
Subclassing an existing Windows control with ATL can significantly reduce your development
time when creating new controls.
<P>
<LI><B>Dual-interface controls</B>
<SPACER TYPE="VERTICAL" SIZE="2">
Unlike MFC, ATL ActiveX controls are dual-interface by default and require no extra
work to implement.
<P>
<LI><B>Advanced ActiveX</B>
<SPACER TYPE="VERTICAL" SIZE="2">
The ATL framework provides advanced features by default.
</UL>
<P>This chapter expands upon the information in <A HREF="ch08.htm">Chapter 8</A>
about creating a basic ATL ActiveX control. In addition to the features that you
are familiar with, such as Clipboard and Drag and Drop support, you will learn how
to implement asynchronous properties and optimized drawing, which are the result
of the adoption of OLE Control 96 (OC 96) specification.
<H2><A NAME="Heading2"></A>Properties</H2>
<H2>Properties</H2>
<P>In <A HREF="ch08.htm">Chapter 8</A>, you learn how to add the various types of
properties to your control implementation. One type of property that has yet to be
examined in terms of ATL is asynchronous properties.
<H3><A NAME="Heading3"></A>Creating Asynchronous Properties</H3>
<P>Asynchronous properties are those properties that typically represent a large
amount of data, such as a text file or a bitmap, and are loaded as a background process
so as not to interfere with the normal processing of the control and the container.
This statement can be somewhat misleading. Asynchronous refers only to the call to
load the data; it does not refer to the actual loading.</P>
<P>For example, a control uses a bitmap as its background and has defined the bitmap
as an asynchronous property. If OLE determines that the bitmap is already on the
local machine, the data is considered to be available to the control and, subsequently,
will instruct the control that all of the data is available. If OLE determines that
the bitmap is not available on the local machine, OLE will load the data as fast
as possible and inform the control as data becomes available. After the data is in
a location that is considered accessible, the property essentially behaves as any
other property would. If you require the asynchronous loading of the data regardless
of its location, you must implement it yourself.</P>
<P>Before you can add your asynchronous property, you need to add the property <TT>ReadyState</TT>,
which is used by the container to determine the state that the control is in at any
given time relative to the loading of asynchronous properties. You also add the event
<TT>ReadyStateChange</TT>, which is used by the control to notify the container that
the <TT>ReadyState</TT> property of the control has changed.</P>
<P>Adding the <TT>ReadyState</TT> property is the same as adding any other property,
as is described in <A HREF="ch08.htm">Chapter 8</A>. From the ClassView tab in the
Project Workspace window, select the <TT>IATLControlWin</TT> interface, click the
right mouse button, and select the Add <U>P</U>roperty menu item.</P>
<P>In the Add Property to Interface dialog, set the Property <U>T</U>ype to <TT>long</TT>,
the Property <U>N</U>ame to <TT>ReadyState</TT>, uncheck the <U>P</U>ut Function
check box, and leave the remainder of the settings at their default values (see fig.
9.1). Click OK to confirm the entry, and close the dialog.</P>
<P>Before you proceed, open the ATLControl.idl file, and change the <TT>dispid</TT>
of the <TT>ReadyState</TT> property to <TT>DISPID_READYSTATE</TT> since <TT>ReadyState</TT>
is a stock property (see Listing 9.1). <B><BR>
<BR>
</B><A HREF="Art/09/xfigs01.jpg"><B>FIG. 9.1</B></A> <BR>
<I>Add the <TT>ReadyState </TT>property to the control using the ATL Object Wizard
for your asynchronous property support.</I></P>
<P>
<H3><A NAME="Heading4"></A>Listing 9.1<SPACER TYPE="HORIZONTAL" SIZE="10"> ATLCONTROL.IDL--Change
the dispid of the ReadyState Property to the Stock Property dispid--DISPID_READYSTATE</H3>
<P><FONT COLOR="#0066FF"><TT>. . . <BR>
interface IATLControlWin : IDispatch <BR>
{ <BR>
[id(1), helpstring("method CaptionMethod")] HRESULT CaptionMethod( <BR>
[in] BSTR bstrCaption, [in, optional] VARIANT varAlignment, <BR>
[out, retval] long * lRetVal); <BR>
[propget, id(DISPID_READYSTATE), helpstring("property ReadyState")] <BR>
HRESULT ReadyState([out, retval] long *pVal); <BR>
[propget, id(DISPID_BACKCOLOR), helpstring("property BackColor")] <BR>
HRESULT BackColor([out, retval] OLE_COLOR *pVal); <BR>
[propput, id(DISPID_BACKCOLOR), helpstring("property BackColor")] <BR>
HRESULT BackColor([in] OLE_COLOR newVal); <BR>
[propget, id(dispidCaptionProp), helpstring("property CaptionProp")] <BR>
HRESULT CaptionProp([in, optional] VARIANT varAlignment, <BR>
[out, retval] BSTR *pVal); <BR>
[propput, id(dispidCaptionProp), helpstring("property CaptionProp")] <BR>
HRESULT CaptionProp([in, optional] VARIANT varAlignment, <BR>
[in] BSTR newVal); <BR>
[propget, id(dispidAlignment), helpstring("property Alignment")] <BR>
HRESULT Alignment([out, retval] long *pVal); <BR>
[propput, id(dispidAlignment), helpstring("property Alignment")] <BR>
HRESULT Alignment([in] long newVal); <BR>
}; <BR>
<BR>
. . . </TT></FONT></P>
<P>The implementation of the <TT>ReadyState</TT> property requires a member variable
to store the <TT>ReadyState</TT> value. Add the <TT>m_lReadyState</TT> member to
the class declaration of the <TT>CATLControlWin</TT> class (see Listing 9.2).
<H3><A NAME="Heading5"></A>Listing 9.2<SPACER TYPE="HORIZONTAL" SIZE="10"> ATLCONTROLWIN.H--Add
the m_lReadyState Member to the CATLControlWin Class</H3>
<P><FONT COLOR="#0066FF"><TT>. . . <BR>
int iCharWidthArray[256]; <BR>
int iCharacterSpacing, iCharacterHeight; <BR>
// for the ReadyState property <BR>
long m_lReadyState; <BR>
}; <BR>
</TT></FONT></P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -