📄 ch07.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!--last modified on Tue, Apr 15, 1997 9:00 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 7</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF">
<H1>Chapter 7<BR>
Advanced ActiveX Control Development with MFC</H1>
<UL>
<LI><A HREF="#Heading1">Advanced ActiveX Control Development with MFC</A>
<UL>
<LI><A HREF="#Heading2">Properties</A>
<UL>
<LI><A HREF="#Heading3">Creating Asynchronous Properties</A>
<LI><A HREF="#Heading4">Listing 7.1 MFCONTROLWINCTL.CPP--Constructor Initialization
of ReadyState</A>
<LI><A HREF="#Heading5">Listing 7.2 MYDATAPATH.H--CString Member Variable Added to
the CMyDataPath Class</A>
<LI><A HREF="#Heading6">Listing 7.3 MFCCONTROWINCTL.H--CMFCControlWinCtrl Class Updated
to Include the CMyDataPath Class</A>
<LI><A HREF="#Heading7">Listing 7.4 MYDATAPATH.CPP--OnDataAvailable Implementation</A>
<LI><A HREF="#Heading8">Listing 7.5 MFCCONTROLWINCTL.CPP--oMyDataPath Object Initialized
in the CMFCControlWinCtrl Class Constructor</A>
<LI><A HREF="#Heading9">Listing 7.6 MFCCONTROLWINCTRL.CPP--oMyDataPath Added to DoPropExchange</A>
<LI><A HREF="#Heading10">Listing 7.7 MFCCONTROLWINCTL.H--Get/Set TextData Property
Implementation</A>
<LI><A HREF="#Heading11">Static and Dynamic Property Enumeration</A>
<LI><A HREF="#Heading12">Listing 7.8 MFCCONTROL.ODL--EALIGNMENT Enumeration Added
to the MFCControl.odl File</A>
<LI><A HREF="#Heading13">Listing 7.9 MFCCONTROLWINCTL.H--Dynamic Property Enumeration
Function Prototypes Added to the CMFCControlWinCtrl Class</A>
<LI><A HREF="#Heading14">Listing 7.10 MFCCONTROLWINCTL.CPP--OnGetPredefinedStrings
Implementation</A>
<LI><A HREF="#Heading15">Listing 7.11 MFCCONTROLWINCTL.H--Control dispid Enumeration</A>
<LI><A HREF="#Heading16">Listing 7.12 MFCCONTROLWINCTL.CPP-- OnGetPredefinedValue
Implementation</A>
<LI><A HREF="#Heading17">Listing 7.13 MFCCONTROLWINCTL.CPP--OnGetDisplayString Implementation</A>
</UL>
<LI><A HREF="#Heading18">Drawing the Control</A>
<UL>
<LI><A HREF="#Heading19">Listing 7.14 MFCCONTROWINCTL.CPP--Optimized OnDraw Function</A>
</UL>
<LI><A HREF="#Heading20">Adding Clipboard and Drag and Drop Support</A>
<UL>
<LI><A HREF="#Heading21">Clipboard Support</A>
<LI><A HREF="#Heading22">Listing 7.15 MFCCONTROLWINCTL.CPP--OnKeyDown Implementation</A>
<LI><A HREF="#Heading23">Listing 7.16 MFCCONTROLWINCTL.H--Clipboard Source Support
Helper Function Prototypes</A>
<LI><A HREF="#Heading24">Listing 7.17 MFCCONTROLWINCTL.CPP--CopyDataToClipboard Implementation</A>
<LI><A HREF="#Heading25">Listing 7.18 MFCCONTROLWINCTL.CPP-- PrepareDataForTransfer
Implementation</A>
<LI><A HREF="#Heading26">Listing 7.19 MFCCONTROLWINCTL.H--Clipboard Target Support
Helper Function Prototypes</A>
<LI><A HREF="#Heading27">Listing 7.20 MFCCONTROLWINCTL.CPP--GetDataFromClipboard
Implementation</A>
<LI><A HREF="#Heading28">Listing 7.21 MFCCONTROLWINCTL.CPP--GetDataFromTransfer Implementation</A>
<LI><A HREF="#Heading29">Drag and Drop Support</A>
<LI><A HREF="#Heading30">Listing 7.22 MFCCONTROLWINCTL.CPP--OnLButtonDown Implementation</A>
<LI><A HREF="#Heading31">Listing 7.23 MFCCONTROLWINCTL.H--CMyOleDropTarget Class
Declaration Added to the CMFCControlWinCtl Class</A>
<LI><A HREF="#Heading32">Listing 7.24 MFCCONTROLWINCTL.CPP--OnCreate Implementation</A>
<LI><A HREF="#Heading33">Listing 7.25 MFCCONTROLWINCTL.CPP--OnDragOver Implementation</A>
<LI><A HREF="#Heading34">Listing 7.26 MFCCONTROLWINCTL.CPP--OnDrop Implementation</A>
<LI><A HREF="#Heading35">Custom Clipboard and Drag and Drop Formats</A>
<LI><A HREF="#Heading36">Listing 7.27 MFCCONTROLWINCTL.H--m_uiCustomFormat Member
Variable Added to the CMFCControlWinCtrl Class</A>
<LI><A HREF="#Heading37">Listing 7.28 MFCCONTROLWINCTL.CPP--Custom Clipboard Format
Registered in the CMFCControlWinCtrl Constructor</A>
<LI><A HREF="#Heading38">Listing 7.29 MFCCONTROLWINCTL.CPP--PrepareDataForTransfer
Function Updated to Support Custom Clipboard Formats</A>
<LI><A HREF="#Heading39">Listing 7.30 MFCCONTROLWINCTL.CPP--GetDataFromTransfer Function
Updated to Support Custom Clipboard Formats</A>
</UL>
<LI><A HREF="#Heading40">Subclassing Existing Windows Controls</A>
<UL>
<LI><A HREF="#Heading41">Listing 7.31 MFCCONTROLSUBWINCTL.CPP--Additional Code Requirements
for ActiveX Controls that Subclass Existing Windows Controls</A>
</UL>
<LI><A HREF="#Heading42">Dual-Interface Controls</A>
<LI><A HREF="#Heading43">Other ActiveX Features</A>
<UL>
<LI><A HREF="#Heading44">Windowless Activation</A>
<LI>
<LI><A HREF="#Heading46">Flicker-Free Activation</A>
<LI><A HREF="#Heading47">Unclipped Device Context</A>
<LI><A HREF="#Heading48">Mouse Pointer Notifications When Inactive</A>
</UL>
<LI><A HREF="#Heading49">From Here...</A>
</UL>
</UL>
<P>
<HR SIZE="4">
<H1><A NAME="Heading1"></A>Advanced ActiveX Control Development with MFC</H1>
<UL>
<LI><B>Adding asynchronous properties</B>
<SPACER TYPE="VERTICAL" SIZE="2">
MFC hides many details of support of asychronous properties, allowing you to focus
on your control implementation.
<P>
<LI><B>Optimized drawing</B>
<SPACER TYPE="VERTICAL" SIZE="2">
Optimized drawing with MFC is easy and can enhance the overall performance of the
control.
<P>
<LI><B>Clipboard and Drag and Drop support</B>
<SPACER TYPE="VERTICAL" SIZE="2">
Using MFC to add Clipboard and Drag and Drop support to mundane control implementations
can have profound effects.
<P>
<LI><B>Subclassing Windows controls</B>
<SPACER TYPE="VERTICAL" SIZE="2">
Subclassing an existing Windows control can reduce your development time when creating
new controls, and MFC can be a hinderance.
<P>
<LI><B>Dual-interface controls</B>
<SPACER TYPE="VERTICAL" SIZE="2">
MFC does not support creation of dual-interface controls by default, but you can
add them.
</UL>
<P>This chapter expands upon the information in <A HREF="ch06.htm">Chapter 6</A>
about creating a basic MFC 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 drawings, which are the result
of the adoption of OC 96 specification.
<H2><A NAME="Heading2"></A>Properties</H2>
<P><A HREF="ch06.htm">Chapter 6</A> tells you how to add the various types of properties
to your control implementation. One type of property has yet to be examined: asynchronous
properties.
<H3><A NAME="Heading3"></A>Creating Asynchronous Properties</H3>
<P><I>Asynchronous properties</I> 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. For example,
a control uses a bitmap as its background and has defined it 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
<I>all</I> 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>Except for a few changes, asynchronous properties are added in the same fashion
as any other property. In <A HREF="ch06.htm">Chapter 6</A>, when you initially create
your control, you have the opportunity to define some ActiveX features, one being
Loads Properties Asynchronously. Choosing this option adds some code to your application
that normally would not be implemented.</P>
<P>First, the stock property <TT>ReadyState</TT> was added to your control. This
property is used to notify the container of the state that the control is in while
loading its properties. The stock event <TT>ReadyStateChange</TT>, which is used
to notify the container that the <TT>ReadyState</TT> of the control has changed,<TT>
</TT>was also added. The last thing that was added was the initialization of the
member variable <TT>m_lReadyState</TT> to <TT>READYSTATE_LOADING</TT> in the controls
constructor (see Listing 7.1).
<H3><A NAME="Heading4"></A>Listing 7.1 MFCONTROLWINCTL.CPP--Constructor Initialization
of ReadyState</H3>
<P><FONT COLOR="#0066FF"><TT>CMFCControlWinCtrl::CMFCControlWinCtrl()<BR>
{<BR>
InitializeIIDs(&IID_DMFCControlWin, &IID_DMFCControlWinEvents);<BR>
m_lReadyState = READYSTATE_LOADING;<BR>
// TODO: Call InternalSetReadyState when the readystate changes.<BR>
// set the alignment to the default of left<BR>
m_lAlignment = EALIGN_LEFT;<BR>
}</TT></FONT></P>
<P>This is the extent of the work that is done for you at the time your project is
created.</P>
<P>The control must have an entry point for OLE to communicate with when notifying
the control when and how much data is available. This is accomplished through the
<TT>CDataPathProperty</TT> or the <TT>CCachedDataPathProperty</TT> class.</P>
<P><TT>CDataPathProperty</TT> is used for data that typically arrives in a continuous
fashion, such as stock market data. <TT>CCachedDataPathProperty</TT> is used for
data that is retrieved once and then stored or cached, such as a file. You must implement
a class in your control that is inherited from one of these classes. To add a new
class, you use the ClassWizard.</P>
<P>For the purposes of this chapter and the sample application, you will implement
an asynchronous property that reads string data from a file and outputs the data
as the caption of the control.</P>
<P>Open the ClassWizard, click the Add C<U>l</U>ass button on any one of the tab
pages, and select the New menu item. In the New Class dialog (see fig. 7.1), enter
the <U>N</U>ame CMyDataPath, select a <U>B</U>ase class of <TT>CCachedDataPathProperty</TT>,
and click the OK button to add the new class. <B><BR>
<BR>
</B><A HREF="Art/07/w_fig01.jpg"><B>FIG. 7.1</B></A> <I><BR>
Add a new <TT>CCachedDataPath Property</TT> class with the ClassWizard.</I></P>
<P>Your control must override the <TT>OnDataAvailable</TT> function within the <TT>CMyDataPath</TT>
class in order to receive data as it becomes available. From the open ClassWizard
dialog, select the Message Maps tab and locate the <TT>OnDataAvailable</TT> message
within the Messa_ges list box. Double-click the <TT>OnDataAvailable</TT> message
to add the method to your class. Click the OK button to close the ClassWizard.</P>
<P>The first step is to add the <TT>cstrMyBuffer</TT> member variable to the <TT>CMyDataPath</TT>
class (see Listing 7.2). The member variable, <TT>cstrMyBuffer</TT>, is used to store
all of the data as it is passed to the <TT>OnDataAvailable</TT> function.
<H3><A NAME="Heading5"></A>Listing 7.2 MYDATAPATH.H--CString Member Variable Added
to the CMyDataPath Class</H3>
<P><FONT COLOR="#0066FF"><TT>. . .<BR>
// Implementation<BR>
protected:<BR>
CString cstrMyBuffer;<BR>
};</TT></FONT>
<PRE><FONT COLOR="#0066FF"></FONT></PRE>
<P>The next step is to update the control class, <TT>CMFCControlWinCtrl</TT>, to
include the header file of the <TT>CMyDataPath</TT> class and also to add a new member
variable, <TT>oMyDataPath</TT> (see Listing 7.3). The <TT>CMyDataPath</TT> class
also needs access to the function <TT>CaptionMethod</TT> in the control so that the
data can be placed in the control when it is all available. Since the <TT>CaptionMethod</TT>
is a protected function, it is necessary to allow the <TT>CMyDataPath</TT> class
access to the function using the C++ <TT>friend</TT> declaration.
<H3><A NAME="Heading6"></A>Listing 7.3 MFCCONTROWINCTL.H--CMFCControlWinCtrl Class
Updated to Include the CMyDataPath Class</H3>
<P><FONT COLOR="#0066FF"><TT>. . .<BR>
#include "alignmentenums.h"<BR>
#include "mydatapath.h"<BR>
/////////////////////////////////////////////////////////////////////////////<BR>
// CMFCControlWinCtrl : See MFCControlWinCtl.cpp for implementation.<BR>
. . .<BR>
friend class CMyDataPath;<BR>
CMyDataPath oMyDataPath;<BR>
};<BR>
. . .</TT></FONT></P>
<P>The next step is to add the code to the <TT>OnDataAvailable</TT> function in the
<TT>CMyDataPath</TT> class to deal with the data as it is sent to the control. The
<TT>OnDataAvailable</TT> method is straightforward (see Listing 7.4). It has two
properties, <TT>dwSize</TT> and <TT>bscfFlag</TT>. <TT>DwSize</TT> is the number
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -