CrashRpt中除了错误处理之外值得学习的地方还是不少的,如屏幕截图、邮件发送。 这里主要提取屏幕截图的功能。
1.从CrashRpt源码目录中分别复制minizip、zlib、libpng到一个目录作为公共库使用,并分别编译它们生成lib,需要设置工程属性为“多线程调试(/MTd)”。
2.在公共目录新建ScreenCap目录,复制ScreenCap.h、ScreenCap.cpp到ScreenCap目录。
3.在你的MFC工程中添加过滤器ScreenCap,并把ScreenCap.h、ScreenCap.cpp导入进来。
4.复制核心代码并做相应修改:
// This method compresses the files contained in the report and produces ZIP archive.
BOOL CompressFileAsZip(vector<CString>vtFiles,CString strZipFileName)
{
CStringA strZipFileNameA;
BOOL bStatus = FALSE;
zipFile hZip = NULL;
CString sMsg;
LONG64 lTotalSize = 0;
LONG64 lTotalCompressed = 0;
BYTE buff[1024];
DWORD dwBytesRead=0;
HANDLE hFile = INVALID_HANDLE_VALUE;
LARGE_INTEGER lFileSize;
BOOL bGetSize = FALSE;
strZipFileNameA=strZipFileName;
hZip = zipOpen(strZipFileNameA, APPEND_STATUS_CREATE);
if(hZip==NULL)
{
TRACE(_T("Failed to create ZIP file."));
goto cleanup;
}
for(vector<CString>::iterator iter=vtFiles.begin();
iter!=vtFiles.end(); ++iter ){
CStringA sDstFileNameA;
CString sFileName=*iter;
int nPos=sFileName.ReverseFind('\\');
if ( nPos!=-1 ){
sDstFileNameA=sFileName.Mid(nPos+1);
}else{
sDstFileNameA=sFileName;
}
CString sDesc = _T("描述");
CStringA sDescA;
sDescA=sDesc;
sMsg.Format(_T("Compressing %s\n"), sDstFileNameA);
TRACE(sMsg);
HANDLE hFile = CreateFile(sFileName,
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
sMsg.Format(_T("Couldn't open file %s\n"), sFileName);
TRACE(sMsg);
continue;
}
bGetSize = GetFileSizeEx(hFile, &lFileSize);
if(!bGetSize)
{
sMsg.Format(_T("Couldn't get file size of %s\n"), sFileName);
TRACE(sMsg);
CloseHandle(hFile);
continue;
}
lTotalSize += lFileSize.QuadPart;
BY_HANDLE_FILE_INFORMATION fi;
GetFileInformationByHandle(hFile, &fi);
SYSTEMTIME st;
FileTimeToSystemTime(&fi.ftCreationTime, &st);
zip_fileinfo info;
info.dosDate = 0;
info.tmz_date.tm_year = st.wYear;
info.tmz_date.tm_mon = st.wMonth;
info.tmz_date.tm_mday = st.wDay;
info.tmz_date.tm_hour = st.wHour;
info.tmz_date.tm_min = st.wMinute;
info.tmz_date.tm_sec = st.wSecond;
info.external_fa = FILE_ATTRIBUTE_NORMAL;
info.internal_fa = FILE_ATTRIBUTE_NORMAL;
int n = zipOpenNewFileInZip( hZip, sDstFileNameA, &info,
NULL, 0, NULL, 0, sDescA, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
if(n!=0)
{
sMsg.Format(_T("Couldn't compress file %s\n"), sDstFileNameA);
TRACE(sMsg);
continue;
}
for(;;)
{
BOOL bRead = ReadFile(hFile, buff, 1024, &dwBytesRead, NULL);
if(!bRead || dwBytesRead==0)
break;
int res = zipWriteInFileInZip(hZip, buff, dwBytesRead);
if(res!=0)
{
zipCloseFileInZip(hZip);
sMsg.Format(_T("Couldn't write to compressed file %s\n"), sDstFileNameA);
TRACE(sMsg);
break;
}
lTotalCompressed += dwBytesRead;
}
zipCloseFileInZip(hZip);
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
}
if(lTotalSize==lTotalCompressed)
bStatus = TRUE;
cleanup:
if(hZip!=NULL)
zipClose(hZip, NULL);
if(hFile!=INVALID_HANDLE_VALUE)
CloseHandle(hFile);
if(bStatus)
TRACE(_T("Finished compressing files...OK"));
else
TRACE(_T("File compression failed."));
sMsg.Format(_T("Total file size for compression is %I64d"), lTotalSize);
return bStatus;
}
void CtestdlgDlg::OnBnClickedOk()
{
CScreenCapture sc;
DWORD dwFlags = CR_AS_VIRTUAL_SCREEN;
CPoint m_ptCursorPos;
GetCursorPos(&m_ptCursorPos);
std::vector<CString> screenshot_names;
CString m_sErrorReportDirName=_T("C:\\");
if(dwFlags==CR_AS_VIRTUAL_SCREEN){
// Take screenshot of entire desktop
CRect rcScreen;
sc.GetScreenRect(&rcScreen);
BOOL bTakeScreenshot = sc.CaptureScreenRect(rcScreen, m_ptCursorPos,
m_sErrorReportDirName, 0, screenshot_names);
if(bTakeScreenshot==FALSE){
return;
}
}else if(dwFlags==CR_AS_MAIN_WINDOW){
// Take screenshot of the main window
CRect rcWnd;
GetWindowRect(&rcWnd);
BOOL bTakeScreenshot = sc.CaptureScreenRect(rcWnd, m_ptCursorPos,
m_sErrorReportDirName, 0, screenshot_names);
if(bTakeScreenshot==FALSE){
return;
}
}else{
// Invalid flags
ATLASSERT(0);
return;
}
// vector<CString>vtFiles;
// vtFiles.push_back(_T("C:\\"));
CompressFileAsZip(screenshot_names,_T("C:\\1.ZIP"));
AfxMessageBox(_T("OK"));
}
5.工程链接输入:libpng\lib\libpngd.lib zlib\lib\zlibd.lib minizip\lib\minizipd.lib