續:
淺談
MFC
的子類化機制和該機制的一個應用(
1
)
BOOL CDumpMsgBox::OnDumpOut(LPSTR pszDumpBuffer, UINT nBufferSize)
{
ASSERT(pszDumpBuffer != NULL && nBufferSize != 0);
ASSERT(AfxIsValidString(pszDumpBuffer, nBufferSize));
// calculate '\n' occur times in buffer.
int
nPosition, nLine = 0;
for
(nPosition = 0; nPosition < (int)nBufferSize; nPosition ++)
if
(pszDumpBuffer[nPosition] == '\0')
break;
(pszDumpBuffer[nPosition] == '\n')
nLine ++;
}
// alloc enough memory for convert.
TCHAR *pszBuffer = (TCHAR*)malloc(sizeof
(TCHAR) * (nPosition + nLine + 64));
// convert all '\n' '\r' or '\n\r' to '\r\n':
TCHAR *pszConvert = pszBuffer;
for
(nPosition = 0; nPosition < (int)nBufferSize; nPosition ++)
break
;
(pszDumpBuffer[nPosition] == '\r')
continue
*pszConvert = _T('\r');
pszConvert ++;
*pszConvert = (TCHAR)pszDumpBuffer[nPosition];
// set end of string.
*pszConvert = '\0';
// set converted dump buffer to the edit control.
m_editDump.AssertValid();
m_editDump.SetWindowText(pszBuffer);
free(pszBuffer);
return
TRUE;
CDumpMsgBox::DoMessageBox(UINT nIDPrompt, UINT nType, UINT nIDHelp)
CString string;
(!string.LoadString(nIDPrompt))
TRACE1("CDumpMsgBox::DoMessageBox error: failed to load message box prompt string 0x%04x.\n",
nIDPrompt);
ASSERT(FALSE);
if
(nIDHelp == (UINT)-1)
nIDHelp = nIDPrompt;
DoMessageBox(string, nType, nIDHelp);
CDumpMsgBox::DoMessageBox(LPCTSTR lpszText, UINT nType, UINT nIDHelp)
nRetCode;
// not call PreCreateWindow to initialize CREATESTRUCT data.
AfxHookWindowCreate(this
);
nRetCode = AfxMessageBox(lpszText, nType, nIDHelp);
(!AfxUnhookWindowCreate())
PostNcDestroy();
void
CDumpMsgBox::DoDumpObject(CObject* pDumpObject)
m_fileDump.AssertValid();
// dump target must exist.
ASSERT(pDumpObject != NULL);
CRuntimeClass* pClass = pDumpObject->GetRuntimeClass();
(pClass == NULL)
;
// unexpect runtime-class value.
(AfxIsValidAddress(pDumpObject, pClass->m_nObjectSize, TRUE))
#ifdef
_DEBUG
pDumpObject->Dump(m_dumpContext);
#else
// ! _DEBUG
m_dumpContext << "a " << pClass->m_lpszClassName <<
" at " << (void*)pDumpObject;
m_dumpContext << "\nHex Dumps: " << pClass->m_nObjectSize <<
" bytes long.\n";
m_dumpContext.HexDump(_T("HEX"), (BYTE*)pDumpObject,
pClass->m_nObjectSize, 8);
#endif
// _DEBUG
CDumpMsgBox::AssertValid() const
CWnd::AssertValid();
(m_editDump.GetSafeHwnd())
ASSERT(AfxIsValidAddress(&m_dumpContext, sizeof(CDumpContext), TRUE));
m_fileDump.AssertValid();
CDumpMsgBox::Dump(CDumpContext& dc) const
(m_hWnd == NULL)
CObject::Dump(dc);
dc << "m_hWnd = NULL\n";
else
CWnd::Dump(dc);
(0 < dc.GetDepth())
dc << "include ";
(NULL == m_editDump.GetSafeHwnd())
m_editDump.CObject::Dump(dc);
m_editDump.Dump(dc);
m_fileDump.Dump(dc);
代碼較為簡單,為
MessageBox
增加了一個
Edit Control
,屬性為
ES_MULTILINE
,
ES_READONLY
ES_AUTOVSCROLL
,并且擁有
WS_EX_CLIENTEDGE
屬性。
該
的内容通過
CMemFile
和
CDumpContext
生成。構造函數
CDumpContext( CFile* pFile )
可以生成一個以
為目标的
執行個體,然後調用
CObject::Dump
,最後通過
CMemFile::Detach
得到包含輸出字元串的緩沖區。
以下是
CDumpMsgBox
的應用示例:
CDumpMsgBox msgBox;
// declare intsance
msgBox.DoDumpObject(&msgBox);
// dump itself
msgBox.DoMessageBox(_T("This message box used class CDumpMsgBox."), MB_OKCANCEL);
// display
以上代碼在
MS Visual C++ 6.0, Win98
下調試通過。