📄 ch12.htm
字号:
{<br>
public:<br>
CDGExtMsgEvents (LPUNKNOWN pParentInterface) {<br>
m_pExchExt = pParentInterface;<br>
m_cRef = 0;<br>
m_bInSubmitState = FALSE;<br>
};<br>
<br>
STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);<br>
inline STDMETHODIMP_(ULONG) AddRef() { ++m_cRef; return m_cRef; };<br>
inline STDMETHODIMP_(ULONG) Release() <br>
{
ULONG ulCount = -m_cRef;<br>
if
(!ulCount) { delete this; }<br>
return
ulCount;};<br>
<br>
STDMETHODIMP OnRead(LPEXchEXTCALLBACK lpeecb);<br>
STDMETHODIMP OnReadComplete(LPEXchEXTCALLBACK lpeecb, ULONG
ulFlags);<br>
STDMETHODIMP OnWrite(LPEXchEXTCALLBACK lpeecb);<br>
STDMETHODIMP OnWriteComplete(LPEXchEXTCALLBACK lpeecb, ULONG
ulFlags);<br>
STDMETHODIMP OnSubmit(LPEXchEXTCALLBACK lpeecb);<br>
STDMETHODIMP_ (VOID)OnSubmitComplete(LPEXchEXTCALLBACK lpeecb,
ULONG ulFlags);<br>
STDMETHODIMP OnCheckNames(LPEXchEXTCALLBACK lpeecb);<br>
STDMETHODIMP OnCheckNamesComplete(LPEXchEXTCALLBACK lpeecb, ULONG
ulFlags);<br>
<br>
<br>
private:<br>
ULONG m_cRef;<br>
HRESULT m_hrOnReadComplete;<br>
BOOL m_bInSubmitState; <br>
LPUNKNOWN m_pExchExt;<br>
<br>
};</font></tt> </p>
</blockquote>
<hr>
<p>This is all there is to the <tt><font FACE="Courier">CDGEXT32.H</font></tt> header
file. Next, you'll review the code for the main extension DLL. </p>
<h3><a NAME="CodingtheMainDLLRoutines"><b>Coding the Main DLL Routines</b></a></h3>
<p>The <tt><font FACE="Courier">CDGEXT32.CPP</font></tt> file contains the main body of
code for the extension. The code file can be divided into five parts:
<ul>
<li><font COLOR="#000000">Initialization and main entry code</font> </li>
<li><font COLOR="#000000">Code for the high-level </font><tt><font FACE="Courier">IExchExt</font></tt>
object </li>
<li><font COLOR="#000000">Code for the </font><tt><font FACE="Courier">IExchExtPropertySheets</font></tt>
object </li>
<li><font COLOR="#000000">Code for the </font><tt><font FACE="Courier">IExchExtMessageEvents</font></tt>
object </li>
<li><font COLOR="#000000">Helper code for local routines</font> </li>
</ul>
<p>Listing 12.5 shows the initialization and main entry code for <tt><font FACE="Courier">CDGEXT32.CPP</font></tt>.
This code handles some basic housekeeping and then establishes the DLL entry point (<tt><font
FACE="Courier">DLLMain</font></tt>) and the callback address for the <tt><font
FACE="Courier">IExchExt</font></tt> object (<tt><font FACE="Courier">ExchEntryPoint</font></tt>).
</p>
<hr>
<blockquote>
<b><p>Listing 12.5. The initialization and main entry code for <tt><font FACE="Courier">CDGEXT32.CPP</font></tt>.
<br>
</b></p>
</blockquote>
<blockquote>
<tt><font FACE="Courier"><p>// ==================================================================
<br>
// CDGEXT32.CPP<br>
// ================================================================== <br>
<br>
//<br>
// module-level defines<br>
//<br>
#define INITGUID<br>
#define USES_IID_IExchExt<br>
#define USES_IID_IExchExtAdvancedCriteria<br>
#define USES_IID_IExchExtAttachedFileEvents<br>
#define USES_IID_IExchExtCommands<br>
#define USES_IID_IExchExtMessageEvents<br>
#define USES_IID_IExchExtPropertySheets<br>
#define USES_IID_IExchExtSessionEvents<br>
#define USES_IID_IExchExtUserEvents<br>
#define USES_IID_IMessage<br>
#define USES_PS_MAPI<br>
<br>
//<br>
// include files<br>
//<br>
#include "CDGEXT32.H"<br>
#include <INITGUID.H><br>
#include <MAPIGUID.H><br>
<br>
//<br>
// local declarations<br>
//<br>
MAPINAMEID NamedID[1]; // for new property<br>
BOOL bSignatureOn = TRUE; // assume it's on<br>
static HINSTAncE ghInstDLL = NULL; // DLL handle<br>
<br>
<br>
// ---------------------------------------------------------------- <br>
// Main Body of routines<br>
//<br>
// These two routines are the initial entry point for the DLL and<br>
// the code that registers the extension DLL.<br>
// ---------------------------------------------------------------- <br>
<br>
//<br>
// to start things off as a DLL<br>
//<br>
BOOL WINAPI DllMain(<br>
HINSTAncE hinstDLL,<br>
DWORD fdwReason,<br>
LPVOID lpvReserved)<br>
{<br>
if (DLL_PROCESS_ATTAch == fdwReason)<br>
{<br>
ghInstDLL = hinstDLL;<br>
<br>
}<br>
return TRUE;<br>
}<br>
<br>
//<br>
// register the extension<br>
//<br>
LPEXchEXT CALLBACK ExchEntryPoint(void)<br>
{<br>
return new CDGExt;<br>
}</font></tt> </p>
</blockquote>
<hr>
<p>Next is the code for the methods and properties of the <tt><font FACE="Courier">IExchExt</font></tt>
object. Along with the initial object constructor code, three methods must be coded:
<ul>
<li><font COLOR="#000000">The </font><tt><font FACE="Courier">QueryInterface</font></tt>
method </li>
<li><font COLOR="#000000">The </font><tt><font FACE="Courier">Install</font></tt> method </li>
<li><font COLOR="#000000">The </font><tt><font FACE="Courier">Release</font></tt> method </li>
</ul>
<p>Listing 12.6 shows the code for the <tt><font FACE="Courier">IExchExt</font></tt>
object. </p>
<hr>
<blockquote>
<b><p>Listing 12.6. Code for the <tt><font FACE="Courier">IExchExt</font></tt> interface.<br>
</b></p>
</blockquote>
<blockquote>
<tt><font FACE="Courier"><p>// ------------------------------------------ <br>
// Handle the creation of the CDGExt object<br>
// ------------------------------------------<br>
//<br>
// These routines establish the initial<br>
// extension interface.<br>
//<br>
// CDGExt::CDGExt() - constructor<br>
// CDGExt::Release() - frees up resources<br>
// CDGExt::QueryInterface() - main entry<br>
// CDGExt::Install() - installs extensions<br>
// --------------------------------------------<br>
<br>
//<br>
// constructor for the propertysheet and message event extension <br>
//<br>
CDGExt::CDGExt()<br>
{<br>
m_cRef = 1;<br>
m_pExchExtPropertySheets = new CDGExtPropSheets(this); <br>
m_pExchExtMessageEvents = new CDGExtMsgEvents(this); <br>
<br>
};<br>
<br>
<br>
//<br>
// frees up resources when done<br>
//<br>
STDMETHODIMP_(ULONG) CDGExt::Release()<br>
{<br>
ULONG ulCount = -m_cRef;<br>
<br>
if (!ulCount)<br>
{<br>
delete this;<br>
}<br>
<br>
return ulCount;<br>
<br>
}<br>
<br>
//<br>
// initial interface query<br>
// for both propertysheets and message events<br>
//<br>
STDMETHODIMP CDGExt::QueryInterface(REFIID riid, LPVOID FAR * ppvObj)<br>
{<br>
HRESULT hResult = S_OK;<br>
<br>
*ppvObj = NULL;<br>
<br>
if (( IID_IUnknown == riid) || ( IID_IExchExt == riid) )<br>
{<br>
*ppvObj = (LPUNKNOWN)this; <br>
}<br>
else if (IID_IExchExtPropertySheets == riid) // for property
sheets?<br>
{<br>
// ignore send/read contexts (for property sheet)<br>
if ( (m_context ==
EECONTEXT_SENDNOTEMESSAGE) ||<br>
(m_context
== EECONTEXT_SENDPOSTMESSAGE) ||<br>
(m_context
== EECONTEXT_SENDRESENDMESSAGE) ||<br>
(m_context
== EECONTEXT_READNOTEMESSAGE) ||<br>
(m_context
== EECONTEXT_READPOSTMESSAGE) ||<br>
(m_context
== EECONTEXT_READREPORTMESSAGE) )<br>
return
E_NOINTERFACE;<br>
<br>
// otherwise return the interface <br>
*ppvObj = (LPUNKNOWN)
m_pExchExtPropertySheets;<br>
}<br>
else if (IID_IExchExtMessageEvents == riid) // for message events?<br>
{<br>
*ppvObj = (LPUNKNOWN)
m_pExchExtMessageEvents;<br>
}<br>
else<br>
hResult = E_NOINTERFACE; <br>
<br>
if (NULL != *ppvObj)<br>
((LPUNKNOWN)*ppvObj)->AddRef(); <br>
<br>
return hResult;<br>
}<br>
<br>
<br>
//<br>
// actually installs the extension<br>
//<br>
STDMETHODIMP CDGExt::Install(LPEXchEXTCALLBACK peecb, ULONG eecontext, ULONG <font
FACE="ZAPFDINGBATS">Â</font>ulFlags)<br>
{<br>
ULONG ulBuildVersion;<br>
HRESULT hr;<br>
<br>
m_context = eecontext;<br>
<br>
// compare versions<br>
peecb->GetVersion(&ulBuildVersion, EECBGV_GETBUILDVERSION);<br>
if (EECBGV_BUILDVERSION_MAJOR != (ulBuildVersion &<br>
EECBGV_BUILDVERSION_MAJOR_MA
SK)) <br>
return S_FALSE; // oops!<br>
<br>
switch (eecontext)<br>
{<br>
case EECONTEXT_PROPERTYSHEETS:<br>
&n
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -