📄 附录a1 建构环境.htm
字号:
cellSpacing=0 cellPadding=0 align=center>
<TBODY>
<TR>
<TD class=ml></TD>
<TD class=mm vAlign=top><BR>
<DIV align=center>
<H1 class=aTitle>Windows2000 服务器端应用程序开发设计指南-附录</H1></DIV>
<TABLE width="97%" align=center>
<TBODY>
<TR>
<TD width=502>
<DIV align=center>[日期:2006-11-6 来源:<A
href="http://www.acejoy.com/" target=_blank>ACE开发者</A><SPAN
id=SourceLabel></SPAN> 作者:Jeffrey Richter
Jason D. Clark<SPAN id=AuthorLabel>]</SPAN></DIV></TD>
<TD align=right width=209>
<DIV align=center>[字体: <INPUT title=把正文字体缩小 style="HEIGHT: 16px" onclick="fontSize('m','ArticleBody')" type=button value=小>
<INPUT title=把正文字体扩大 style="HEIGHT: 16px" onclick="fontSize('b','ArticleBody')" type=button value=大>
<INPUT title=转为简体中文模式 style="HEIGHT: 16px" onclick="bodytojt('ArticleBody')" type=button value=简>
<INPUT title=转为繁体中文模式 style="HEIGHT: 16px" onclick="bodytoft('ArticleBody')" type=button value=繁>
<A href="javascript:fontColor('ArticleBody')"><IMG alt=字体颜色
src="附录A1 建构环境.files/fgcolor.gif" align=absMiddle
border=0></A>]</DIV></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=5 cellPadding=0 width="100%" align=center border=0>
<TBODY>
<TR>
<TD vAlign=top>
<TABLE cellSpacing=0 cellPadding=10 align=left border=0>
<TBODY>
<TR>
<TD></TD></TR></TBODY></TABLE>
<DIV class=content id=ArticleBody
style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">
<P class=content>
<TABLE border=0>
<TBODY style="LINE-HEIGHT: 25px">
<TR>
<TD align=middle><FONT style="LINE-HEIGHT: 25px" face=arial
color=#000000 size=2><FONT style="LINE-HEIGHT: 25px"
face=arial color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> 列表B-1 </B></FONT>EnsureCleanup.h标头文件</FONT></TD></TR></TBODY></TABLE>
<CENTER></CENTER></A><A style="LINE-HEIGHT: 25px" name=102002>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">Print Buffer之C++
类别(PrintBuf.h)<BR style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>许多书中的范例应用程序建构了资讯的字串。然后这个资讯会被放入一个静态控制项或唯读的编辑控制项中,不然就是被显示在一个讯息方块里。列示在列表B-2中的CprintBuf类别让建构这些字串的工作变得更简单。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>CprintBuf物件会持续追踪一个字串缓冲器。每一次Print或PrintError方法被呼叫时,新的字串资讯就会被新增至字串后方。如您所见,预测字串所需的储存空间是很困难的,因为应用程序没有办法提前知道将被放入的字串为何。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>为了有效地使用内存,CprintBuf的字串缓冲器经由保留一个较大的内存区块而被初始。因为它不会使用一个小于系统配置的大略值(迄今所有的Windows平台上皆为64
KB),所以我们将它预设为64
KB大小。在保留这个区域后,会提交一个储存分页给它。如果字串资料试图使用超过此储存范围,则会产生一个例外,而CprintBuf物件会提交更多储存空间给缓冲器,增加所需的内存。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>此类别多载(overload)了PCTSTR的转型运算子,使得类别的实例可被直接传递给需要一个指向包含以零结尾字串的缓冲器函数。</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">PrintBuf.h <BR>/******************************************************************** <BR>模组:PrintBuf.h <BR>通告:Copyright (c)2000 Jeffrey Richter <BR>目的:此类别包装了在自动地增加资料缓冲器时允许sprintf类的操作。 <BR>请参阅附录B <BR>********************************************************************/ <BR>#pragma once // 每个编辑单元皆须包含此标头档 <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#include "..\CmnHdr.h" // 请参阅附录A <BR>#include <StdIO.h> // 为了 _vstprintf而包含 <BR>/////////////////////////////////////////////////////////////////////////////// <BR>class CPrintBuf { <BR>public: <BR> CPrintBuf(SIZE_T nMaxSizeInBytes = 64 * 1024); // 预设为64 KB <BR> virtual ~CPrintBuf(); <BR> BOOL Print(PCTSTR pszFmt, ...); <BR> BOOL PrintError(DWORD dwError = GetLastError()); <BR> operator PCTSTR() {return(m_pszBuffer);} <BR> void Clear(); <BR>private: <BR> LONG Filter(EXCEPTION_POINTERS* pep); <BR>private: <BR> int m_nMaxSizeInBytes; <BR> int m_nCurSize; <BR> PTSTR m_pszBuffer; <BR>}; <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#ifdef PRINTBUF_IMPL <BR>/////////////////////////////////////////////////////////////////////////////// <BR>CPrintBuf::CPrintBuf(SIZE_T nMaxSizeInBytes) { <BR> // 此建构者设定成员的间隔值并保留一个nMaxSizeInBytes大小的位址区块,并且提交单一分页 <BR> m_nMaxSizeInBytes = nMaxSizeInBytes; <BR> m_nCurSize = 0; <BR> m_pszBuffer = (PTSTR) <BR> VirtualAlloc(NULL, m_nMaxSizeInBytes, MEM_RESERVE, PAGE_READWRITE); <BR> chASSERT(m_pszBuffer != NULL); <BR> chVERIFY(VirtualAlloc(m_pszBuffer, 1, MEM_COMMIT, PAGE_READWRITE) != NULL); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>CPrintBuf::~CPrintBuf() { <BR> VirtualFree(m_pszBuffer, 0, MEM_RELEASE); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>void CPrintBuf::Clear() { <BR> VirtualFree(m_pszBuffer, m_nMaxSizeInBytes, MEM_DECOMMIT); <BR> chVERIFY(VirtualAlloc(m_pszBuffer, 1, MEM_COMMIT, PAGE_READWRITE) != NULL); <BR> m_nCurSize = 0; <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>LONG CPrintBuf::Filter(EXCEPTION_POINTERS* pep) { <BR> LONG lDisposition = EXCEPTION_EXECUTE_HANDLER; <BR> EXCEPTION_RECORD* per = pep->ExceptionRecord; <BR> __try { <BR> // 检查产生的例外是否为一个在资料缓冲器区域的存取违规? <BR> if (per->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) <BR> __leave; <BR> if (!chINRANGE(m_pszBuffer, (PVOID) per->ExceptionInformation[1], <BR> ((PBYTE) m_pszBuffer) + m_nMaxSizeInBytes - 1)){ <BR> __leave; <BR> } <BR> // 试图提交内存到该区域 <BR> if (VirtualAlloc((PVOID) pep->ExceptionRecord->ExceptionInformation[1], <BR> 1, MEM_COMMIT, PAGE_READWRITE) == NULL) { <BR> __leave; <BR> } <BR> lDisposition = EXCEPTION_CONTINUE_EXECUTION; <BR> } <BR> __finally { <BR> } <BR> return(lDisposition); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>int CPrintBuf::Print(PCTSTR pszFmt , ...) { <BR> // 此函数增加文字至格式化的列印缓冲器 <BR> int nLength = -1; // Assume failure <BR> va_list arglist; <BR> va_start(arglist, pszFmt); <BR> __try { <BR> // 新增字串到缓冲器的结尾 <BR> nLength = _vstprintf(m_pszBuffer + m_nCurSize, pszFmt, arglist); <BR> if (nLength > 0) <BR> m_nCurSize += nLength; <BR>} <BR> __except (Filter(GetExceptionInformation())) { <BR> chMB("CPrintBuf attempted to go over the maximum size."); <BR> DebugBreak(); <BR> } <BR> va_end(arglist); <BR> return(nLength); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>BOOL CPrintBuf::PrintError(DWORD dwErr) { <BR> // 新增最后的错误字串文字至缓冲器 <BR> PTSTR pszMsg = NULL; <BR> BOOL fOk = (0 != FormatMessage( <BR> FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, <BR> dwErr, 0, (PTSTR) &pszMsg, 0, NULL)); <BR> fOk = fOk && (Print(TEXT("Error %d: %s"), dwErr, pszMsg) >= 0); <BR> if (pszMsg != NULL) <BR> LocalFree(pszMsg); <BR> return(fOk); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#endif // PRINTBUF_IMPL <BR>///////////////////////////////// End of File /////////////////////////////////</PRE></FONT></DIV>
<CENTER style="LINE-HEIGHT: 25px">
<TABLE border=0>
<TBODY style="LINE-HEIGHT: 25px">
<TR>
<TD align=middle><FONT style="LINE-HEIGHT: 25px" face=arial
color=#000000 size=2><FONT style="LINE-HEIGHT: 25px"
face=arial color=#3e80d7 size=2><B
style="LINE-HEIGHT: 25px"> 列表B-2 </B></FONT>PrintBuf.h标头文件</FONT></TD></TR></TBODY></TABLE></CENTER></A><A
style="LINE-HEIGHT: 25px" name=102003>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#3e70d7
size=5><B style="LINE-HEIGHT: 25px">Auto Buffer之C++
范本类别(AutoBuf.h)<BR style="LINE-HEIGHT: 25px"> </B></FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>许多Windows函数需要使用缓冲器,所以您必须配置它。一般的情形下,您没有办法在呼叫一个函数前得知正确的缓冲器大小,所以为了这些Windows函数,您必须先呼叫函数一次,取得所需的缓冲器大小,然后再配置缓冲器,最后再呼叫函数一秒钟以实际地将资料放入缓冲器内。当然这是相当不方便的。再加上呼叫函数期间可能会改变缓冲器大小的需求,因为Windows是一个先占式(Preemptive)的多线程作业系统。在一些情况中,您第二次对函数的呼叫可能会失败。虽然执行失败的可能性相当小,但是一个良好的应用程序编写应确实地将这部份列入考虑并使用好的设计风格及优美的处理方式。例如,以下为需要使用RegQueryValueEx取得一个适当登录值的程序代码:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">ULONG uValSize = 1; <BR>PTSTR pszValue = NULL; <BR>LONG lErr; <BR>do { <BR> if (uValSize != 0) { <BR> if (pszValue != NULL) { <BR> HeapFree(GetProcessHeap(), 0, pszValue); <BR> } <BR> pszValue = (PTSTR)HeapAlloc(GetProcessHeap(), 0, uValSize); <BR> if (pszValue == NULL) { <BR> // 错误:未显示适当的处理方式 <BR> } <BR> } <BR> // 假设hkey已被初始 <BR> lErr = RegQueryValueEx(hkey, TEXT("SomeValueName"), NULL, <BR> NULL, (PBYTE) pszValue, &uValSize); <BR>}while (lErr == ERROR_MORE_DATA); <BR>if (lErr != ERROR_SUCCESS){ <BR> // 错误:未显示适当的处理方式 <BR>}</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>接下来的程序代码片段执行了相同的功能,但是为了配置缓冲器而使用CautoBuf函数。一个附加的特色是,当物件超出使用范围时,缓冲器会自动地被释放。</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">CAutoBuf<PTSTR, sizeof(TCHAR)> pszValue; <BR>pszValue = 1; <BR>LONG lErr; <BR>do { <BR> lErr = RegQueryValueEx(hkey, TEXT("SomeValueName"), NULL, NULL, <BR> pszValue, pszValue); <BR>} while (lErr == ERROR_MORE_DATA); <BR>if (lErr != ERROR_SUCCESS){ <BR> // 错误:未显示适当的处理方式 <BR>}</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>列于列表B-3的CautoBuf之C++
类别使需要紧握缓冲器的函数得以正常工作。一个CautoBuf物件配置一个资料缓冲器,经由任何Windows函数告知会自动地决定其大小。另外,当物件超出使用范围时,CautoBuf物件会自动地释放它的资料缓冲器。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>由于CautoBuf之C++
类别是一个样版类别,所以它支援使用任何资料型别的缓冲器。要使用此类别,您可以简单地用您想要持有的资料型别宣告一个实例。以下是一个CautoBuf的范例,它应该包含一个QUERY_SERVICE_CONFIG结构(其长度可变):</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">CAutoBuf<QUERY_SERVICE_CONFIG> pServiceConfig;</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>现在可以开始将资料填入缓冲器,您必须使用以下的方法呼叫QueryServiceConfig函数:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL fOk; <BR>fOk = QueryServiceConfig( <BR> hService, // hService (SC_HANDLE) <BR> pServiceConfig, // pServiceConfig (QUERY_SERVICE_CONFIG*) <BR> pServiceConfig, // cbBufferSize (DWORD) <BR> pServiceConfig); // pcbBytesNeeded (PDWORD)</PRE></FONT></DIV>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>您应该会注意到该函数传递了pServiceConfig物件给叁个参数,这是因为CautoBuf类别在物件上使用了叁个转型方法:一个回传资料缓冲器位址的转型方法,一个以位元组大小回传资料缓冲器大小的DWORD转型方法,以及一个回传将被用所需缓冲器大小填入的一个DWORD成员变数之PDWORD转型方法。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>如果传递给cbBufferSize参数的值太小,QueryServiceConfig会回传FALSE,且随后对GetLastError的呼叫会回传ERROR_INSUFFICIENT_BUFFER值。在这个情形下,您需要做的事就是再呼叫QueryServiceConfig一次,此时缓冲器会自动调整至pcbBytesNeeded参数回传的大小。这一次QueryServiceConfig应该可以成功地填入缓冲器,并回传非零值。</FONT></P>
<P><FONT style="LINE-HEIGHT: 25px" face=arial color=#000000
size=2>然而,QueryServiceConfig仍然有可能执行失败,因为另一个线程可能会改变服务的状态资讯。所以良好的应用程序编写方式应该重覆地呼叫QueryServiceConfig,直到它执行成功为止。为了使这个工作变得容易些,我们在AutoBuf.h文件的结尾处加入了GROWUNTIL巨集。这个巨集在一个回圈中重覆地呼叫了所需的函数,直到该函数执行成功或产生除了ERROR_INSUFFICIENT_BUFFER或ERROR_MORE_DATA的错误为止。以下列出一个范例,说明如何使用此巨集:</FONT></P>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">BOOL fOk; <BR>GROWUNTIL(FALSE, <BR>fOk = QueryServiceConfig( <BR> hService, // hService (SC_HANDLE) <BR> pServiceConfig, // pServiceConfig (QUERY_SERVICE_CONFIG*) <BR> pServiceConfig, // cbBufferSize (DWORD) <BR> pServiceConfig)); // pcbBytesNeeded (DWORD*)</PRE></FONT></DIV>
<DIV style="LINE-HEIGHT: 25px; BACKGROUND-COLOR: #d7d7d7"><FONT
style="LINE-HEIGHT: 25px" face=Arial size=3><PRE style="LINE-HEIGHT: 25px">AutoBuf.h <BR>/******************************************************************** <BR>模组:AutoBuf.h <BR>通告:Copyright (c)2000 Jeffrey Richter <BR>目的:此类别管理一个自动调整大小的资料缓冲器。 <BR> 请参阅附录B <BR>********************************************************************/ <BR>#pragma once // 编辑单元时需要包含此标头文件 <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#include "..\CmnHdr.h" // 请参阅附录A <BR>///////////////////CautoBuf之C++ 样板类别说明/////////////////// <BR>/* <BR>CautoBuf之C++ 样板类别实作安全的缓冲器型别,自动增加程序代码所需的大小。当物件被删除时 <BR>(通常是在您的程序代码超出框架范围以及从堆叠中被释放时),内存也会自动被释放。 <BR>使用范例: <BR> // 用不明确的资料型别建立一个缓冲器, <BR> // 此时缓冲器会以一个位元组的方式增加 <BR> CAutoBuf<PVOID> buf; <BR> // 建立TCHARs型别的缓冲器, <BR> // 此时缓冲器会以sizeof(TCHAR) 的方式增加 <BR> CAutoBuf<PTSTR, sizeof(TCHAR)>buf; <BR> // 强迫此缓冲器为10位元组大 <BR> buf = 10; <BR>*/ <BR>/////////////////////////////////////////////////////////////////////////////// <BR>// 此类别只用做CautoBuf样板类别的基础类别。 <BR>// 基础类别已经存在,使得样板类别实例分享一般程序代码的单一实例。 <BR>class CAutoBufBase { <BR>public: <BR> UINT Size() {return(* (PDWORD) PSize()); } <BR> UINT Size(UINT uSize); <BR> PUINT PSize() { <BR> AdjustBuffer(); <BR> m_uNewSize = m_uCurrentSize; <BR> return(&m_uNewSize); <BR> } <BR> void Free() {Reconstruct(); } <BR>protected: <BR> CAutoBufBase(PBYTE *ppbData, int nMult) { <BR> m_nMult = nMult; <BR> m_ppbBuffer = ppbData; // 取得保存缓冲器位址的类别,以允许 <BR> // 侦错器用已分类的型别工作 <BR> Reconstruct(TRUE); <BR> } <BR> virtual ~CAutoBufBase() { Free(); } <BR> void Reconstruct(BOOL fFirstTime = FALSE); <BR> PBYTE Buffer() { <BR> AdjustBuffer(); <BR> return(*m_ppbBuffer); <BR> } <BR>private: <BR> void AdjustBuffer(); <BR>private: <BR> PBYTE* m_ppbBuffer; // 资料缓冲器的位址 <BR> Int m_nMult; // 为了增加缓冲器所使用的Multiplier(以位元组为单位) <BR> UINT m_uNewSize; // 请求的缓冲器大小(在m_nMult单元中) <BR> UINT m_uCurrentSize; // 实际的大小(在m_nMult单元中) <BR>}; <BR>/////////////////////////////////////////////////////////////////////////////// <BR>template <class TYPE, int MULT = 1> <BR>class CAutoBuf :private CAutoBufBase { <BR>public: <BR> CAutoBuf() : CAutoBufBase((PBYTE*) &m_pData, MULT) {} <BR> void Free() { CAutoBufBase::Free(); } <BR>public: <BR> operator TYPE*() { return(Buffer()); } <BR> UINT operator=(UINT uSize) { return(CAutoBufBase::Size(uSize)); } <BR> operator UINT() { return(Size()); } <BR> operator ULONG() { return(Size()); } <BR> operator PUINT() { return(PSize()); } <BR> operator PLONG() { return((PLONG)PSize()); } <BR> operator PULONG() { return((PULONG)PSize()); } <BR> operator PBYTE() { return((PBYTE)Buffer()); } <BR> operator PVOID() { return((PVOID)Buffer()); } <BR> TYPE& operator[](int nIndex) { return(*(Buffer() + nIndex)); } <BR>private: <BR> TYPE* Buffer() { return((TYPE*) CAutoBufBase::Buffer()); } <BR>private: <BR> TYPE* m_pData; <BR>}; <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#define GROWUNTIL(fail, func) \ <BR> do { \ <BR> if ((func) != (fail)) \ <BR> break; \ <BR> }while ((GetLastError() == ERROR_MORE_DATA) || \ <BR> (GetLastError() == ERROR_INSUFFICIENT_BUFFER)); <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#ifdef AUTOBUF_IMPL <BR>/////////////////////////////////////////////////////////////////////////////// <BR>void CAutoBufBase::Reconstruct(BOOL fFirstTime) { <BR> if (!fFirstTime) { <BR> if (*m_ppbBuffer != NULL) <BR> HeapFree(GetProcessHeap(), 0, *m_ppbBuffer); <BR> } <BR> *m_ppbBuffer = NULL; // 取得没有指向资料缓冲器的类别 <BR> m_uNewSize = 0; // 缓冲器中没有资料 <BR> m_uCurrentSize = 0; // 缓冲器中没有资料 <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>UINT CAutoBufBase::Size(UINT uSize) { <BR> // 设定缓冲器去要求m_nMult大小的位元组 <BR> if (uSize == 0) { <BR> Reconstruct(); <BR> } else { <BR> m_uNewSize = uSize; <BR> AdjustBuffer(); <BR> } <BR> return(m_uNewSize); <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>void CAutoBufBase::AdjustBuffer(){ <BR>if (m_uCurrentSize < m_uNewSize) { <BR> // 我们开始增加缓冲器大小 <BR> HANDLE hHeap = GetProcessHeap(); <BR> if (*m_ppbBuffer != NULL) { <BR> // 我们已经重新设定缓冲器大小 <BR> PBYTE pNew = (PBYTE) <BR> HeapReAlloc(hHeap, 0, *m_ppbBuffer, m_uNewSize * m_nMult); <BR> if (pNew != NULL) { <BR> m_uCurrentSize = m_uNewSize; <BR> *m_ppbBuffer = pNew; <BR> } <BR> } else { <BR> // 我们没有缓冲器,建立一个新的 <BR> *m_ppbBuffer = (PBYTE)HeapAlloc(hHeap, 0, m_uNewSize *m_nMult); <BR> if (*m_ppbBuffer != NULL) <BR> m_uCurrentSize = m_uNewSize; <BR> } <BR> } <BR>} <BR>/////////////////////////////////////////////////////////////////////////////// <BR>#endif // AUTOBUF_IMPL <BR>///////////////////////////////// End of File /////////////////////////////////</PRE></FONT></DIV>
<CENTER style="LINE-HEIGHT: 25px">
<P></P>
<P class=content_page><A
href="http://www.acejoy.com/Html/Article/network/6920061106222109.html">上一页</A> <A
href="http://www.acejoy.com/Html/Article/network/6920061106222109.html">[1]</A> <STRONG><FONT
color=#ff0033>[2]</FONT></STRONG> <A
href="http://www.acejoy.com/Html/Article/network/6920061106222109_P3.html">[3]</A> <A
href="http://www.acejoy.com/Html/Article/network/6920061106222109_P4.html">[4]</A> <A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -