天天看點

淺談 MFC 的子類化機制和該機制的一個應用(2)

續:

淺談

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

下調試通過。