DebugView源代码

自己实现一个DebugView

#include "stdafx.h"
#include "SimpleDbgView.h"
#include "SimpleDbgViewDlg.h"

#include <new>
#include "FilterDlg.h"
#include "ScreenCapture.h"
#include "ClipBoardHelp.h"
#include "aboutdlg.h"
using namespace std;

#define WM_USER_ADDLOG (WM_USER+0x1002)

CSimpleDbgViewDlg::CSimpleDbgViewDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSimpleDbgViewDlg::IDD, pParent)
	, m_strPID(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
	m_pList = NULL;
	m_bAutoScroll = 0;
	m_bExclude = 0;
	m_dwPID = 0xFFFFFFFF;
}

void CSimpleDbgViewDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, m_strPID);
}

BEGIN_MESSAGE_MAP(CSimpleDbgViewDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_DESTROY()
	ON_MESSAGE(WM_USER_ADDLOG, OnAddMsg)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BUTTON1, &CSimpleDbgViewDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CSimpleDbgViewDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CSimpleDbgViewDlg::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &CSimpleDbgViewDlg::OnBnClickedButton4)
	ON_COMMAND(ID_FILE_SAVELOG, &CSimpleDbgViewDlg::OnFileSavelog)
	ON_COMMAND(ID_FILE_EXIT, &CSimpleDbgViewDlg::OnFileExit)
	ON_COMMAND(ID_FILE_SAVEAS, &CSimpleDbgViewDlg::OnFileSaveas)
	ON_COMMAND(ID_HELP_ABOUT, &CSimpleDbgViewDlg::OnHelpAbout)
	ON_COMMAND(ID_FILTER_EDITFILTERS, &CSimpleDbgViewDlg::OnFilterEditfilters)
	ON_EN_CHANGE(IDC_EDIT1, &CSimpleDbgViewDlg::OnEnChangeEdit1)
	ON_BN_CLICKED(IDC_BUTTON5, &CSimpleDbgViewDlg::OnBnClickedButton5)
	ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, &CSimpleDbgViewDlg::OnLvnKeydownList1)
END_MESSAGE_MAP()

LRESULT CSimpleDbgViewDlg::OnAddMsg(WPARAM wp, LPARAM lp)
{
	CString* str = (CString*)wp;

	if(str)
	{
		if(m_pList)
		{
			WCHAR szTime[100];
			swprintf(szTime, L"%u", GetTickCount());
			int rc = m_pList->GetItemCount();
			m_pList->InsertItem(rc , szTime);
			m_pList->SetItemText(rc , 1, (*str));

			if(rc == 0)
			{
				RECT rcC;
				::GetClientRect(m_hWnd, &rcC);
				int cx = rcC.right - rcC.left;
				int cy = rcC.bottom - rcC.top;
				OnSize(0, cx, cy);
			}

			if(m_bAutoScroll)
			{
				m_pList->EnsureVisible(rc, FALSE); //设置滚动条到最下面
				//nColumn为当前记录条数
			}
		}

		delete str;
	}

	return 0;
}

BOOL CSimpleDbgViewDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
	CMenu* pSysMenu = GetSystemMenu(FALSE);

	if(pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);

		if(!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标
	//
	m_custom_list.SubclassDlgItem(IDC_LIST1, this);
	m_pList = &m_custom_list;
	InitList();
	StartDbgThread();
	SetWindowPos(0, 0, 0, _S(800), _S(600), SWP_NOZORDER | SWP_NOMOVE);
	return TRUE;
}

void CSimpleDbgViewDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		if(nID == SC_CLOSE)
		{
			EndDialog((IDOK));
			return;
		}

		CDialog::OnSysCommand(nID, lParam);
	}
}

void CSimpleDbgViewDlg::OnPaint()
{
	if(IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文
		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CSimpleDbgViewDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CSimpleDbgViewDlg::OnDestroy()
{
	m_custom_list.UnsubclassWindow();
	CDialog::OnDestroy();
}

void CSimpleDbgViewDlg::OnSize(UINT nType, int cx, int cy)
{
	if(m_pList)
	{
		m_pList->SetWindowPos(0, 0, _S(20), cx  , cy - _S(20), SWP_NOZORDER);
	}
}

void CSimpleDbgViewDlg::InitList()
{
	if(m_pList)
	{
		m_pList->SetExtendedStyle(m_pList->GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_SINGLEROW);
		m_pList->InsertColumn(0, L"Tick Time", LVCFMT_LEFT, 100);
		m_pList->InsertColumn(1, L"Dbg Print", LVCFMT_LEFT, 1800);
		m_pList->DeleteAllItems();
	}
}

/***************************************************************************************
*
*   关于DebugLog如何抓取的代码
*
**************************************************************************************/
#define MAX_DEBUG_BUF_LEN (4096)
#pragma pack(push)
#pragma pack(1)
typedef struct __DEBUGBUFFER
{
	DWORD dwPID;
	char szString[MAX_DEBUG_BUF_LEN - sizeof(DWORD)];

} DEBUGBUFFER, *PDEBUGBUFFER;
#pragma pack(pop)


DWORD WINAPI __get_log_thread(LPVOID lpp)
{
	CSimpleDbgViewDlg* pDlg = (CSimpleDbgViewDlg*)lpp;

	if(!pDlg)
		return -1;

	HANDLE hReadyEvent = NULL;
	DWORD dwResult = ERROR_INVALID_HANDLE;
	HANDLE hMapping = NULL;
	HANDLE hAckEvent = NULL;
	PDEBUGBUFFER pdbBuffer = NULL;

	do
	{
		hAckEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("DBWIN_BUFFER_READY"));// 打开事件句柄

		if(!hAckEvent)
			break;

		hReadyEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("DBWIN_DATA_READY"));

		if(!hReadyEvent)
			break;

		// 创建文件映射
		hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAX_DEBUG_BUF_LEN, TEXT("DBWIN_BUFFER"));

		if(!hMapping)
			break;

		// 映射调试缓冲区
		pdbBuffer = (PDEBUGBUFFER) MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

		if(pdbBuffer == NULL)
			break;

		for(dwResult = ERROR_SIGNAL_PENDING; (dwResult == ERROR_SIGNAL_PENDING);)
		{
			SetEvent(hAckEvent);//发给调用OutputDebugString的程序,告诉他,缓冲区已经就绪

			// 等待缓冲区数据
			if(WaitForSingleObject(hReadyEvent, INFINITE) == WAIT_OBJECT_0)
			{
				// 如果是继续等待,否则表示主线程发出了停止信号,退出当前线程
				if(dwResult == ERROR_SIGNAL_PENDING)
				{
					// 添加新项
					pDlg->AddLogItem(pdbBuffer->dwPID, pdbBuffer->szString);
				}
			}
			else
			{
				// 等待失败
				dwResult = WAIT_ABANDONED;
			}
		}
	}
	while(0);

	// 释放
	if(pdbBuffer)
		UnmapViewOfFile(pdbBuffer);

	if(hMapping)
		CloseHandle(hMapping);

	if(hReadyEvent)
		CloseHandle(hReadyEvent);

	if(hAckEvent)
		CloseHandle(hAckEvent);

	return dwResult;
}

void CSimpleDbgViewDlg::StartDbgThread()
{
	HANDLE hThread =::CreateThread(0, 0, __get_log_thread, this, 0, 0);
}

void CSimpleDbgViewDlg::AddLogItem(DWORD dwPID, char* szString)
{
	if(szString)
	{
		if(m_dwPID != 0xFFFFFFFF && dwPID != m_dwPID)
		{
			return;
		}

		if(Filter_Pass(szString))
		{
			return;
		}

		CString* strDbgAdd = new(nothrow)CString;

		if(strDbgAdd)
		{
			strDbgAdd->Format(L"[%u] %s", dwPID, CStringW(szString));
			this->PostMessage(WM_USER_ADDLOG, (WPARAM)strDbgAdd);
		}
	}
}


void CSimpleDbgViewDlg::OnBnClickedButton1()
{
	// TODO: Save
	SaveLog();
}

void CSimpleDbgViewDlg::OnBnClickedButton2()
{
	// TODO: Clear
	if(m_pList)
	{
		m_pList->DeleteAllItems();
	}
}

void CSimpleDbgViewDlg::OnBnClickedButton3()
{
	// TODO: AutoScroll
	m_bAutoScroll = TRUE;
}

void CSimpleDbgViewDlg::OnBnClickedButton4()
{
	// TODO: NotAutoScroll
	m_bAutoScroll = FALSE;
}

void CSimpleDbgViewDlg::OnFileSavelog()
{
	// TODO:
	SaveLog();
}

void CSimpleDbgViewDlg::SaveLog()
{
	if(m_strLogFileName.GetLength())
	{
		_SaveLog(m_strLogFileName);
	}
	else
	{
		m_strLogFileName = SelectFile();
		_SaveLog(m_strLogFileName);
	}
}

void CSimpleDbgViewDlg::OnFileExit()
{
	EndDialog(IDOK);
}

void CSimpleDbgViewDlg::OnFileSaveas()
{
	m_strLogFileName = L"";
	SaveLog();
}

void CSimpleDbgViewDlg::_SaveLog(CString strLogFileName)
{
	if(strLogFileName.GetLength())
	{
		if(m_pList)
		{
			FILE* fp = _wfopen(strLogFileName, L"wb+");

			if(fp)
			{
				SetWindowText(strLogFileName);
				int rc = m_pList->GetItemCount();

				for(int i = 0; i < rc; i++)
				{
					CString strItem1 = m_pList->GetItemText(i, 0);
					CString strItem2 = m_pList->GetItemText(i, 1);
					CStringA strS;
					strS.Format("[%s] %s\r\n", CStringA(strItem1), CStringA(strItem2));
					fwrite((LPCSTR)strS, 1, strS.GetLength(), fp);
				}

				fclose(fp);
			}
		}
	}
}

CString CSimpleDbgViewDlg::SelectFile()
{
	CString strRet;
	CFileDialog fd(0, L".log", m_strLogFileName.GetLength() ? m_strLogFileName : L"SimpleDbgView.log");

	if(fd.DoModal() == IDOK)
	{
		strRet = fd.GetPathName();
	}

	return strRet;
}

void CSimpleDbgViewDlg::OnHelpAbout()
{
	// TODO: 在此添加命令处理程序代码
	CAboutDlg dlgAbout;
	dlgAbout.DoModal();
}

void CSimpleDbgViewDlg::OnFilterEditfilters()
{
	// TODO: 在此添加命令处理程序代码
	FilterDlg dlg;
	dlg.DoModal();
	LoadCfg();
}

const char * __cdecl strstr_i(const char * str1, const char * str2)
{
	const char *cp = (char *) str1;
	const char *s1, *s2;

	if(!*str2)
		return((char *)str1);

	while(*cp)
	{
		s1 = cp;
		s2 = (char *) str2;

		while(*s1 && *s2 && !(toupper(*s1) - toupper(*s2)))
			s1++, s2++;

		if(!*s2)
			return(cp);

		cp++;
	}

	return(NULL);
}

CMyCriticalSection lock_filter;

bool CSimpleDbgViewDlg::Filter_Pass(char* szString)
{
	bool bRet = true;

	if(szString)
	{
		CAutoCriticalSection lock(lock_filter.GetSection());

		if(//命中过滤条件
		    m_strKeyW1.GetLength() && strstr_i(szString, m_strKeyW1) ||
		    m_strKeyW2.GetLength() && strstr_i(szString, m_strKeyW2) ||
		    m_strKeyW3.GetLength() && strstr_i(szString, m_strKeyW3) ||
		    m_strKeyW4.GetLength() && strstr_i(szString, m_strKeyW4)
		)
		{
			if(m_bExclude)//排除的
				bRet = true;//不要
			else//包含的
				bRet = false;//要
		}
		else//未命中条件
		{
			if(
			    m_strKeyW1.GetLength() ||
			    m_strKeyW2.GetLength() ||
			    m_strKeyW3.GetLength() ||
			    m_strKeyW4.GetLength()
			)
			{
				if(m_bExclude)
					bRet = false;
				else
					bRet = true;
			}
			else//没有设置过滤的
			{
				bRet = false; //要
			}
		}
	}

	return bRet;
}

void CSimpleDbgViewDlg::LoadCfg()
{
	CAutoCriticalSection lock(lock_filter.GetSection());
	WCHAR szDll[MAX_PATH] = {};
	::GetModuleFileName(NULL, szDll, MAX_PATH);
	CString strCfg = CString(szDll) + L".ini";
	WCHAR szTxt[1000] = {};
	GetPrivateProfileStringW(L"Cfg", L"K1", L"", szTxt, _countof(szTxt), strCfg);
	m_strKeyW1 = CStringA(szTxt);
	GetPrivateProfileStringW(L"Cfg", L"K2", L"", szTxt, _countof(szTxt), strCfg);
	m_strKeyW2 = CStringA(szTxt);
	GetPrivateProfileStringW(L"Cfg", L"K3", L"", szTxt, _countof(szTxt), strCfg);
	m_strKeyW3 = CStringA(szTxt);
	GetPrivateProfileStringW(L"Cfg", L"K4", L"", szTxt, _countof(szTxt), strCfg);
	m_strKeyW4 = CStringA(szTxt);
	GetPrivateProfileStringW(L"Cfg", L"bex", L"", szTxt, _countof(szTxt), strCfg);
	m_bExclude = _wtoi(szTxt);
}

void CSimpleDbgViewDlg::OnEnChangeEdit1()
{
	UpdateData(TRUE);

	if(m_strPID.GetLength())
	{
		m_dwPID = _wtoi(m_strPID);
	}
	else
	{
		m_dwPID = 0xFFFFFFFF;
	}
}

void CSimpleDbgViewDlg::OnBnClickedButton5()
{
	AfxGetScreenCaptureWin().CaptureScreen(0);
	AfxGetScreenCaptureWin().SetMyDlg(this);
	AfxGetScreenCaptureWin().ShowSnapWindow();
}

void CSimpleDbgViewDlg::setPIDByHwnd(HWND m_hCurrentHWND)
{
	DWORD dwPid = 0;
	GetWindowThreadProcessId(m_hCurrentHWND, &dwPid);
	m_strPID.Format(L"%u", dwPid);
	UpdateData(0);
	OnEnChangeEdit1();
}

void CSimpleDbgViewDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
	*pResult = 0;
}

void CSimpleDbgViewDlg::OnLvnKeydownList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);

	if(m_pList && GetKeyState('C') & 0x8000 &&
	        GetKeyState(VK_CONTROL) & 0x8000)
	{
		int sl = m_pList->GetSelectionMark();
		int rc = m_pList->GetItemCount();

		if(sl >= 0 && sl < rc)
		{
			CString str1 = m_pList->GetItemText(sl, 0);
			CString str2 = m_pList->GetItemText(sl, 1);
			CString strClipboard;
			strClipboard.Format(L"%s %s", str1, str2);
			GetClipBoard().SetClipBoard_SimpleText(strClipboard);
		}
	}

	*pResult = 0;
}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值