续: 浅谈MFC的子类化机制和该机制的一个应用(1)
BOOL CDumpMsgBox::OnDumpOut(LPSTR pszDumpBuffer, UINT nBufferSize)
{
ASSERT(pszDumpBuffer != NULL && nBufferSize != 0);
ASSERT(AfxIsValidString(pszDumpBuffer, nBufferSize));
// calculate ' ' occur times in buffer.
int nPosition, nLine = 0;
for (nPosition = 0; nPosition < (int)nBufferSize; nPosition ++)
{
if (pszDumpBuffer[nPosition] == '')
break;
if (pszDumpBuffer[nPosition] == ' ')
nLine ++;
}
// alloc enough memory for convert.
TCHAR *pszBuffer = (TCHAR*)malloc(sizeof(TCHAR) * (nPosition + nLine + 64));
// convert all ' ' ' ' or ' ' to ' ':
TCHAR *pszConvert = pszBuffer;
for (nPosition = 0; nPosition < (int)nBufferSize; nPosition ++)
{
if (pszDumpBuffer[nPosition] == '')
break;
if (pszDumpBuffer[nPosition] == ' ')
continue;
if (pszDumpBuffer[nPosition] == ' ')
{
*pszConvert = _T(' ');
pszConvert ++;
}
*pszConvert = (TCHAR)pszDumpBuffer[nPosition];
pszConvert ++;
}
// set end of string.
*pszConvert = '';
// set converted dump buffer to the edit control.
m_editDump.AssertValid();
m_editDump.SetWindowText(pszBuffer);
free(pszBuffer);
return TRUE;
}
int CDumpMsgBox::DoMessageBox(UINT nIDPrompt, UINT nType, UINT nIDHelp)
{
CString string;
if (!string.LoadString(nIDPrompt))
{
TRACE1("CDumpMsgBox::DoMessageBox error: failed to load message box prompt string 0x%04x. ",
nIDPrompt);
ASSERT(FALSE);
}
if (nIDHelp == (UINT)-1)
nIDHelp = nIDPrompt;
return DoMessageBox(string, nType, nIDHelp);
}
int CDumpMsgBox::DoMessageBox(LPCTSTR lpszText, UINT nType, UINT nIDHelp)
{
int nRetCode;
// not call PreCreateWindow to initialize CREATESTRUCT data.
AfxHookWindowCreate(this);
nRetCode = AfxMessageBox(lpszText, nType, nIDHelp);
if (!AfxUnhookWindowCreate())
PostNcDestroy();
return nRetCode;
}
void CDumpMsgBox::DoDump (C * pDump )
{
m_fileDump.AssertValid(); // dump target must exist.
ASSERT(pDump != NULL);
CRuntimeClass* pClass = pDump ->GetRuntimeClass();
if (pClass == NULL)
return; // unexpect runtime-class value.
if (AfxIsValidAddress(pDump , pClass->m_n Size, TRUE))
{
#ifdef _DEBUG
pDump ->Dump(m_dumpContext);
#else // ! _DEBUG
m_dumpContext << "a " << pClass->m_lpszClassName <<
" at " << (void*)pDump ;
m_dumpContext << " Hex Dumps: " << pClass->m_n Size <<
" bytes long. ";
m_dumpContext.HexDump(_T("HEX"), (BYTE*)pDump ,
pClass->m_n Size, 8);
#endif // _DEBUG
}
}
#ifdef _DEBUG
void CDumpMsgBox::AssertValid() const
{
CWnd::AssertValid();
if (m_editDump.GetSafeHwnd())
m_editDump.AssertValid();
ASSERT(AfxIsValidAddress(&m_dumpContext, sizeof(CDumpContext), TRUE));
m_fileDump.AssertValid();
}
void CDumpMsgBox::Dump(CDumpContext& dc) const
{
if (m_hWnd == NULL)
{
C ::Dump(dc);
dc << "m_hWnd = NULL ";
}
else
CWnd::Dump(dc);
if (0 < dc.GetDepth())
{
dc << "include ";
if (NULL == m_editDump.GetSafeHwnd())
{
m_editDump.C ::Dump(dc);
dc << "m_hWnd = NULL ";
}
else
m_editDump.Dump(dc);
dc << "include ";
m_fileDump.Dump(dc);
}
}
#endif // _DEBUG
代码较为简单,为 MessageBox 增加了一个 Edit Control ,属性为 ES_MULTILINE ,ES_READONLY, ES_AUTOVSCROLL,并且拥有 WS_EX_CLIENTEDGE 属性。
该 Edit Control 的内容通过 CMemFile 和 CDumpContext 生成。构造函数 CDumpContext( CFile* pFile ) 可以生成一个以 CMemFile 为目标的 CDumpContext 实例,然后调用 C ::Dump,最后通过 CMemFile::Detach 得到包含输出字符串的缓冲区。
以下是 CDumpMsgBox 的应用示例:
CDumpMsgBox msgBox; // declare intsance
msgBox.DoDump (&msgBox); // dump itself
msgBox.DoMessageBox(_T("This message box used class CDumpMsgBox."), MB_OKCANCEL); // display
以上代码在 MS Visual C++ 6.0, Win98 下调试通过。
继续阅读与本文标签相同的文章
-
Sun 微博 Slynkr 部署记录
2026-06-02栏目: 教程
-
取得 WinNT/2000 下的用户名
2026-06-02栏目: 教程
-
实现 Rundll.exe 功能的简单代码
2026-06-02栏目: 教程
-
利用 AttachThreadInput 改变其它进程的输入法状态
2026-06-02栏目: 教程
-
Squid 2.6 STABLE 6 配置与管理指南
2026-06-02栏目: 教程
