📄 ch10.htm
字号:
<BR>
<BR>
In this chapter, you will create three controls: a standard control, a windowless
control, and a subclassed control. All three will be combined into a single control
module to give you a feel for how it is done. None of the sample controls is meant
to be a fully functional control. They are used only to give you an understanding
of how to implement specific features and functionality with a minimum of effort.
Again, since you do not have an application wizard at your disposal, you must create
your project by hand. To create a new BaseCtl project, you need to perform the following
steps:
<UL>
<LI>Create a directory for the new project. In this case, call the new project directory
BCFControl.
<P>
<LI>Copy all of the files from the BCFBasicControl sample directory to the new directory.
Change the names of the files from BCFBasicControl to your project name. In this
case, change the names to BCFControl.
<P>
<LI>Using an application, such as Visual C++, that is capable of doing text replacement,
change all of the BCFBasicControl entries to the name of your control. In this case,
change the name BCFBasicControl to BCFControl and BCFBASICCONTROL to BCFCONTROL,
respectively. Remember to change every file that was copied from the basic project
and perform the replacement on a case-sensitive basis.
<P>
<LI>Generate new <TT>UUID</TT>s with GUIDGEN.EXE. See <A HREF="ch02.htm">Chapter
2</A> for more information about GUIDGEN.EXE and how it is used. Replace the four
<TT>UUI</TT>s in the ODL file and the one property page <TT>UUID</TT> in the Guids.h
file.
<P>
<LI>Modify the Dwinvers.h file to reflect the version and company information that
is appropriate for your project.
</UL>
<P>After you modify all of the files, you are ready to use your new project. Open
the Visual C++ development environment, and from the <U>F</U>ile menu, select the
Open Workspace menu item. In the Open Workspace dialog, change to the directory of
your newly created project (\Que\ActiveX\BCFControl), and open the BCFControl.dsw
file (see fig. 10.1). <BR>
<BR>
<A HREF="Art/10/hfig01.jpg"><B>FIG. 10.1</B></A> <I><BR>
Open the new project with the Open Workspace dialog.</I></P>
<P>Unlike with the MFC and ATL projects, to support more than one control within
the application, you must add all of the code and files by hand since you do not
have an AppWizard. The simplest way to create additional controls is to repeat the
steps described earlier and copy the appropriate code and files into your base project.
You will create two additional controls named <TT>BCFControlNoWinControl</TT>, which
is a windowless control, and <TT>BCFControlSubWinControl</TT>, which will subclass
a BUTTON window.</P>
<P>After creating the two new projects, as described in the preceding paragraph,
copy the following files to the BCFControl directory.
<UL>
<LI>BCFControlNoWinCtl.bmp
<LI>BCFControlNoWinCtl.cpp
<LI>BCFControlNoWinCtl.h
<LI>BCFControlNoWinPPG.cpp
<LI>BCFControlNoWinPPG.h
<LI>BCFControlSubWinCtl.bmp
<LI>BCFControlSubWinCtl.cpp
<LI>BCFControlSubWinCtl.h
<LI>BCFControlSubWinPPG.cpp
<LI>BCFControlSubWinPPG.h
</UL>
<P>Ensure that the BCFControl project is open within the VC++ IDE, and from the <U>P</U>roject
menu, select the <U>A</U>dd to Project menu item and the <U>F</U>iles submenu. In
the Insert Files into Project dialog, select the files BCFControlNoWinCtl.Cpp, BCFControlNoWinPPG.Cpp,
BCFControlSubWinCtl.Cpp, and BCFControlSubWinPPG.Cpp, and click the OK button (see
fig. 10.2). <B><BR>
<BR>
</B><A HREF="Art/10/hfig02.jpg"><B>FIG. 10.2</B></A> <I><BR>
Use the Insert Files into Project dialog to add the files of the <TT>BCFControlNoWin</TT>
and <TT>BCFControlSubWin</TT> control to the base project.</I></P>
<P>After you add all of the files that you need to your project, you still have to
do some cut and paste operations from the remaining files to complete the integration
of the three controls.</P>
<P>You need to include the header files from your new control projects to the main
application file (see Listing 10.1).</P>
<P>The BaseCtl framework supports a globally declared array for describing all of
the OLE components included within the application. The <TT>OBJECTINFO</TT> array,
as it is called, should contain an entry for each control, property page, and automation
server you want to declare within your module. You need to add your additional control
and property page declarations to the <TT>OBJECTINFO</TT> array.
<H3><A NAME="Heading4"></A>Listing 10.1 <SPACER TYPE="HORIZONTAL" SIZE="10">BCFCONTROL.CPP--Include
New Control Header Files and Control Declarations</H3>
<P><FONT COLOR="#0066FF"><TT>//=--------------------------------------------------------------------------=<BR>
<BR>
// BCFControl.Cpp //=--------------------------------------------------------------------------=
<BR>
... <BR>
#include "BCFControlCtl.H"<BR>
#include "BCFControlPPG.H"<BR>
#include "BCFControlNoWinCtl.H"<BR>
<BR>
#include "BCFControlNoWinPPG.H"<BR>
#include "BCFControlSubWinCtl.H"<BR>
#include "BCFControlSubWinPPG.H" <BR>
... <BR>
//=--------------------------------------------------------------------------=<BR>
// This Table describes all the automatible objects in your automation server.<BR>
// See AutomationObject.H for a description of what goes in this structure<BR>
// and what it's used for.<BR>
//<BR>
OBJECTINFO g_ObjectInfo[] = {<BR>
CONTROLOBJECT(BCFControl),<BR>
PROPERTYPAGE(BCFControlGeneral),<BR>
CONTROLOBJECT(BCFControlNoWin),<BR>
PROPERTYPAGE(BCFControlNoWinGeneral),<BR>
CONTROLOBJECT(BCFControlSubWin),<BR>
PROPERTYPAGE(BCFControlSubWinGeneral), EMPTYOBJECT<BR>
};</TT></FONT></P>
<P><FONT COLOR="#0066FF"><TT>...</TT></FONT></P>
<P>The ODL compiler will generate a C++ header file for accessing the interfaces
declared in the application. Since you are combining all three controls into a single
project, you will have a single interface file to deal with. The two additional control
implementations must be changed to reflect the new file. In the BCFControlNoWinCtl.h
header file, you need to change the include file<FONT COLOR="#0066FF"><TT><BR>
<BR>
#include "BCFControlNoWinInterfaces.H"</TT></FONT></P>
<P>to<FONT COLOR="#0066FF"><TT><BR>
<BR>
#include "BCFControlInterfaces.H"</TT></FONT></P>
<P>The same must be done for the BCFControlSubWinCtl.h header file.</P>
<P>Each of the individual projects contains a Guids.h file. You combine all three
into a single file (see Listing 10.2).
<H3><A NAME="Heading5"></A>Listing 10.2 <SPACER TYPE="HORIZONTAL" SIZE="10">GUIDS.H--Combined
Guids.h</H3>
<P><FONT COLOR="#0066FF"><TT>#ifndef _GUIDS_H_ <BR>
// for each property page this server will have, put the guid definition for it<BR>
// here so that it gets defined ...<BR>
//<BR>
DEFINE_GUID(CLSID_BCFControlGeneralPage, 0x317512F4, 0x3E75, 0x11d0,<BR>
0xBE, 0xBE, 0x00, 0x40, 0x05, 0x38, 0x97, 0x7D); <BR>
DEFINE_GUID(CLSID_BCFControlNoWinGeneralPage, 0xcf395064, 0x3fb6, 0x11d0,<BR>
0xbe, 0xc1, 0x00, 0x40, 0x05, 0x38, 0x97, 0x7d); <BR>
DEFINE_GUID(CLSID_BCFControlSubWinGeneralPage, 0x02456be4, 0x3fb7, 0x11d0,<BR>
0xbe, 0xc1, 0x00, 0x40, 0x05, 0x38, 0x97, 0x7d); <BR>
#define _GUIDS_H_ <BR>
#endif // _GUIDS_H_</TT></FONT></P>
<P>Next you need to combine all of the ODL files into a single file. While it is
possible for an application to contain more than one type library resource, for simplicity,
you will have one. Copy only the interface entries from each of the ODL files, and
insert them into the BCFControl.odl file (see Listing 10.3).
<H3><A NAME="Heading6"></A>Listing 10.3 <SPACER TYPE="HORIZONTAL" SIZE="10">BCFCONTROL.ODL--Combined
Control ODL Files</H3>
<P><FONT COLOR="#0066FF"><TT>//=--------------------------------------------------------------------------=<BR>
// BCFControl.ODL<BR>
//=--------------------------------------------------------------------------=<BR>
// Copyright 1995 Microsoft Corporation. All Rights Reserved.<BR>
//<BR>
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF <BR>
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO <BR>
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A <BR>
// PARTICULAR PURPOSE.<BR>
//=--------------------------------------------------------------------------=<BR>
//<BR>
// ODL file for the control(s) and automation object(s) in this inproc server<BR>
//<BR>
#include <olectl.h><BR>
#include "dispids.h" <BR>
// can't include oaidl.h, so this will have to do<BR>
//<BR>
#define DISPID_NEWENUM -4 //=--------------------------------------------------------------------------=<BR>
// the libid for this type libray<BR>
//<BR>
[<BR>
uuid(317512F0-3E75-11d0-BEBE-00400538977D),<BR>
helpstring("BCFControl Control Library"),<BR>
lcid(0x0000),<BR>
version(1.0)<BR>
]<BR>
library BCFControlObjects { <BR>
// standard imports<BR>
//<BR>
importlib("STDOLE32.TLB");<BR>
importlib(STDTYPE_TLB); <BR>
// primary dispatch interface for CBCFControl control<BR>
//<BR>
[<BR>
uuid(317512F1-3E75-11d0-BEBE-00400538977D),<BR>
helpstring("BCFControl Control"),<BR>
hidden,<BR>
dual,<BR>
odl<BR>
]<BR>
interface IBCFControl : IDispatch { <BR>
// properties<BR>
// <BR>
// methods<BR>
//<BR>
[id(DISPID_ABOUTBOX)]<BR>
void AboutBox(void);<BR>
}; <BR>
// event interface for CBCFControl controls ...<BR>
//<BR>
[<BR>
uuid(317512F2-3E75-11d0-BEBE-00400538977D),<BR>
helpstring("Event interface for BCFControl control"),<BR>
hidden<BR>
]<BR>
dispinterface DBCFControlEvents {<BR>
properties:<BR>
methods:<BR>
}; <BR>
// coclass for CBCFControl controls<BR>
//<BR>
[<BR>
uuid(317512F3-3E75-11d0-BEBE-00400538977D),<BR>
helpstring("BCFControl control")<BR>
]<BR>
coclass BCFControl {<BR>
[default] interface IBCFControl;<BR>
[default, source] dispinterface DBCFControlEvents;<BR>
}; <BR>
// primary dispatch interface for CBCFControlNoWin control<BR>
//<BR>
[<BR>
uuid(cf395061-3fb6-11d0-bec1-00400538977d),<BR>
helpstring("BCFControlNoWin Control"),<BR>
hidden,<BR>
dual,<BR>
odl<BR>
]<BR>
interface IBCFControlNoWin : IDispatch { <BR>
// properties<BR>
// <BR>
// methods<BR>
//<BR>
[id(DISPID_ABOUTBOX)]<BR>
void AboutBox(void);<BR>
}; <BR>
// event interface for CBCFControlNoWin controls ...<BR>
//<BR>
[<BR>
uuid(cf395062-3fb6-11d0-bec1-00400538977d),<BR>
helpstring("Event interface for BCFControlNoWin control"),<BR>
hidden<BR>
]<BR>
dispinterface DBCFControlNoWinEvents {<BR>
properties:<BR>
methods:<BR>
}; <BR>
// coclass for CBCFControlNoWin controls<BR>
//<BR>
[<BR>
uuid(cf395063-3fb6-11d0-bec1-00400538977d),<BR>
helpstring("BCFControlNoWin control")<BR>
]<BR>
coclass BCFControlNoWin {<BR>
[default] interface IBCFControlNoWin;<BR>
[default, source] dispinterface DBCFControlNoWinEvents;<BR>
}; <BR>
// primary dispatch interface for CBCFControlSubWin control<BR>
//<BR>
[<BR>
uuid(02456be1-3fb7-11d0-bec1-00400538977d),<BR>
helpstring("BCFControlSubWin Control"),<BR>
hidden,<BR>
dual,<BR>
odl<BR>
]<BR>
interface IBCFControlSubWin : IDispatch { <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -