406 lines
10 KiB
C++
406 lines
10 KiB
C++
// StatusDlg.cpp : implementation file
|
|
//
|
|
// Allows the user to peep inside the program by allowing
|
|
// the programmer to end data to its screen.
|
|
// It also will log the data to a file.
|
|
//
|
|
// (c) 1991-99 Andy Whittaker, Chester, England.
|
|
// mail@andywhittaker.com
|
|
//
|
|
|
|
#include "StatusDlg.h"
|
|
|
|
#include "cderr.h" // for CommDlgExtendedError()
|
|
#include "strsafe.h"
|
|
#include "FreeScan.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusDlg dialog
|
|
|
|
|
|
CStatusDlg::CStatusDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CStatusDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CStatusDlg)
|
|
//}}AFX_DATA_INIT
|
|
//Load hide status
|
|
CWinApp* pApp = AfxGetApp();
|
|
m_hidden = pApp->GetProfileInt(_T("StatusDlg"), _T("Hide Status"), FALSE);
|
|
m_csLogFile = pApp->GetProfileString(_T("StatusDlg"), _T("Log Filename"), _T(""));
|
|
|
|
m_WindowPos.left = 0;
|
|
m_WindowPos.right = 0;
|
|
m_WindowPos.top = 0;
|
|
m_WindowPos.bottom = 0;
|
|
}
|
|
|
|
CStatusDlg::~CStatusDlg()
|
|
{
|
|
if (m_file.m_hFile != CFile::hFileNull)
|
|
{ // close our log file if it's open
|
|
m_file.Flush();
|
|
m_file.Close(); // close the logging file when we exit.
|
|
}
|
|
|
|
//Save hide status
|
|
CWinApp* pApp = AfxGetApp();
|
|
pApp->WriteProfileInt(_T("StatusDlg"), _T("Hide Status"), m_hidden);
|
|
pApp->WriteProfileString(_T("StatusDlg"), _T("Log Filename"), m_csLogFile);
|
|
|
|
StartLog(FALSE);// close the logging file when we exit.
|
|
}
|
|
|
|
void CStatusDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CStatusDlg)
|
|
DDX_Control(pDX, IDC_TIME, m_Time);
|
|
DDX_Control(pDX, IDC_STATUS, m_Status);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CStatusDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CStatusDlg)
|
|
ON_WM_MOVE()
|
|
ON_WM_DESTROY()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusDlg access functions
|
|
|
|
//WriteStatus enters text into the list box at the end of the list
|
|
void CStatusDlg::WriteStatus(CString csText)
|
|
{ //CListBox
|
|
|
|
if (m_hidden) // don't write to window when hidden
|
|
return;
|
|
|
|
// TRACE_T(("%s\n"), csText);
|
|
if (IsWindow(m_hWnd))
|
|
{
|
|
PumpMessages();
|
|
if(m_Status.GetCount() == 100) // Maximum number of strings we want
|
|
{
|
|
// TRACE("Listbox > 100 items, deleting first string\n");
|
|
m_Status.DeleteString(0);
|
|
}
|
|
m_Status.AddString(csText); // Add the new string in again.
|
|
SendDlgItemMessage(IDC_STATUS, WM_VSCROLL , MAKEWPARAM(SB_LINEDOWN, NULL), NULL );
|
|
}
|
|
|
|
if (m_file.m_pStream != NULL) // i.e. we have a file open
|
|
{
|
|
csText = csText + _T("\n"); // Line Feed while we log to disk
|
|
m_file.WriteString(csText);
|
|
}
|
|
if (IsWindow(m_hWnd))
|
|
UpdateWindow();
|
|
}
|
|
|
|
//WriteStatus enters text into the list box at the end of the list with timestamp
|
|
void CStatusDlg::WriteStatusTimeLogged(CString csText)
|
|
{
|
|
if (m_hidden) // don't write to window when hidden
|
|
return;
|
|
|
|
CString csBuf;
|
|
m_now = CTime::GetCurrentTime();
|
|
csBuf = m_now.Format("%d %b %y %H:%M:%S - ");
|
|
if (IsWindow(m_Time.m_hWnd))
|
|
m_Time.SetWindowText(csBuf); // Updates the time string
|
|
csBuf = csBuf + csText;
|
|
|
|
WriteStatus(csBuf);
|
|
}
|
|
|
|
//Writes the contents of the given buffer as a Hex-dump
|
|
void CStatusDlg::WriteASCII(const unsigned char* const buffer, int ilength)
|
|
{
|
|
if (m_hidden) // don't write to window when hidden
|
|
return;
|
|
|
|
CString cs;
|
|
int iIndex;
|
|
|
|
// Hmmm, I'm sure there's a better way of doing this.
|
|
for(iIndex=0; iIndex < ilength; iIndex++)
|
|
{
|
|
CString csTemp;
|
|
csTemp.Format(_T("0x%02X "), buffer[iIndex]);
|
|
cs = cs + csTemp; // concatenate string
|
|
}
|
|
|
|
// Now write the string.
|
|
WriteStatusTimeLogged(cs);
|
|
}
|
|
|
|
//Writes a formatted log entry to the log file
|
|
// e.g. WriteLogEntry("Program started");
|
|
// WriteLogEntry("Processed %d bytes", 91341);
|
|
// WriteLogEntry("%d error(s) found in %d line(s)", 10, 1351);
|
|
// WriteLogEntry("Program completed");
|
|
void CStatusDlg::WriteLogEntry(LPCTSTR pstrFormat, ...)
|
|
{
|
|
if (m_hidden) // don't write to window when hidden
|
|
return;
|
|
|
|
if (m_file.m_hFile == CFile::hFileNull)
|
|
{ // No log-file open
|
|
return;
|
|
}
|
|
|
|
CTime timeWrite;
|
|
timeWrite = CTime::GetCurrentTime();
|
|
|
|
// write the time out
|
|
CString str = timeWrite.Format("%d %b %y %H:%M:%S - ");
|
|
m_file.Write(str, str.GetLength());
|
|
|
|
// format and write the data we were given
|
|
va_list args;
|
|
va_start(args, pstrFormat);
|
|
str.FormatV(pstrFormat, args);
|
|
m_file.Write(str, str.GetLength());
|
|
|
|
// put a newline
|
|
m_file.Write("\n", 1);
|
|
return;
|
|
}
|
|
|
|
// Starts or stops logging to file
|
|
BOOL CStatusDlg::StartLog(BOOL bStart)
|
|
{
|
|
CString csBuf = _T("");
|
|
|
|
if (!bStart)
|
|
{ // we want to close the logging file
|
|
if (m_file.m_hFile != CFile::hFileNull)
|
|
{
|
|
WriteStatusTimeLogged(_T("Log file stopped"));
|
|
m_file.Close(); // close the logging file when we exit.
|
|
}
|
|
else
|
|
WriteStatusTimeLogged(_T("Log file is already closed"));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// We now must want to log to a file
|
|
|
|
OPENFILENAME ofn;
|
|
memset(&ofn, 0, sizeof(ofn)); // initialize structure to 0/NULL
|
|
TCHAR szFileName[_MAX_PATH] = { 0 }; // contains full path name after return
|
|
TCHAR szFileTitle[_MAX_PATH] = { 0 };
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.lpstrFile = szFileName;
|
|
ofn.nMaxFile = _countof(szFileName);
|
|
ofn.lpstrFileTitle = (LPTSTR)szFileTitle;
|
|
ofn.nMaxFileTitle = _countof(szFileTitle);
|
|
ofn.lpstrTitle = _T("Create/Open Logging File");
|
|
ofn.lpstrFilter = _T("log Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0\0");
|
|
ofn.lpstrInitialDir = m_csLogFile.GetString();
|
|
ofn.lpstrDefExt = _T("txt");
|
|
|
|
// setup initial file name from the registry
|
|
//lstrcpyn(szFileName, m_csLogFile, _countof(szFileName));//unsafe
|
|
StringCchCopy(szFileName, _countof(szFileName), m_csLogFile.GetString());
|
|
|
|
ofn.Flags = OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
|
|
|
|
int nResult = ::GetSaveFileName(&ofn);
|
|
|
|
if (nResult == 0) // Handle the error
|
|
{
|
|
DWORD dwerror = CommDlgExtendedError();
|
|
switch (dwerror)
|
|
{
|
|
case 0 : // no error
|
|
csBuf.Format(_T("User cancelled/closed file Dialog"));
|
|
break; // cancel or closed was pressed
|
|
case FNERR_BUFFERTOOSMALL :
|
|
csBuf.Format(_T("Buffer too small"));
|
|
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
|
|
break;
|
|
case FNERR_INVALIDFILENAME :
|
|
csBuf.Format(_T("Invalid file name"));
|
|
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
|
|
break;
|
|
case CDERR_MEMALLOCFAILURE :
|
|
csBuf.Format(_T("Memory allocation failure"));
|
|
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
|
|
break;
|
|
case CDERR_MEMLOCKFAILURE :
|
|
csBuf.Format(_T("Memory lock failure"));
|
|
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
|
|
break;
|
|
default:
|
|
csBuf.Format(_T("An unknown error has occured - %ld"), dwerror);
|
|
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
|
|
}
|
|
WriteStatus(csBuf);
|
|
return FALSE;
|
|
}
|
|
|
|
// Copy filename from our dialog to the CString member variable
|
|
m_csLogFile.Format(_T("%s"),ofn.lpstrFile);
|
|
|
|
if (!m_file.Open(m_csLogFile, CFile::modeCreate | CFile::modeReadWrite | CFile::typeText))
|
|
{
|
|
csBuf.Format(_T("Cannot open %s"), m_csLogFile.GetString());
|
|
WriteStatus(csBuf);
|
|
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
|
|
return FALSE;
|
|
}
|
|
|
|
WriteStatusTimeLogged(_T("Log file has started"));
|
|
|
|
/*
|
|
// Construct our File Dialog
|
|
CFileDialog Dialog(FALSE, "txt",
|
|
m_csLogFile,
|
|
OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT,
|
|
"log Files (*.txt)|*.txt|All Files (*.*)|*.*||", NULL);
|
|
|
|
// Change the title
|
|
Dialog.m_ofn.lpstrTitle = "Create/Open Logging File";
|
|
|
|
// Display the dialog box
|
|
if (Dialog.DoModal() == IDOK)
|
|
{
|
|
m_csLogFile = Dialog.GetPathName();
|
|
|
|
if (!m_file.Open(m_csLogFile, CFile::modeCreate | CFile::modeReadWrite | CFile::typeText))
|
|
{
|
|
csBuf.Format("Cannot open %s", m_csLogFile);
|
|
WriteStatus(csBuf);
|
|
AfxMessageBox(csBuf, MB_OK | MB_ICONSTOP );
|
|
return FALSE;
|
|
}
|
|
|
|
WriteStatusLogged("Log file has started");
|
|
}
|
|
else // User pressed cancel
|
|
WriteStatus("User cancelled log file");
|
|
*/
|
|
if (m_file.m_hFile != CFile::hFileNull)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
// Hides the status window from view
|
|
void CStatusDlg::Hide(BOOL yes)
|
|
{
|
|
if (yes)
|
|
{
|
|
m_hidden = TRUE;
|
|
if (::IsWindow(m_hWnd))
|
|
ShowWindow(SW_HIDE);
|
|
}
|
|
else
|
|
{
|
|
m_hidden = FALSE;
|
|
if (::IsWindow(m_hWnd))
|
|
ShowWindow(SW_SHOW);
|
|
}
|
|
}
|
|
|
|
// Hide status of window
|
|
BOOL CStatusDlg::IsHidden(void)
|
|
{
|
|
return m_hidden;
|
|
}
|
|
|
|
// Ensures window receives messages and updates correctly
|
|
void CStatusDlg::PumpMessages(void)
|
|
{
|
|
// Must call Create() before using the dialog
|
|
ASSERT(m_hWnd!=NULL);
|
|
|
|
MSG msg;
|
|
// Handle dialog messages
|
|
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
{
|
|
if(!IsDialogMessage(&msg))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// This is for debugging. Prints the current screen coordinates.
|
|
void CStatusDlg::PrintRect(LPRECT lpR)
|
|
{
|
|
CString csData;
|
|
csData.Format(_T("Rect Data:\nleft = %li\ntop = %li\nright = %li\nbottom = %li"),
|
|
lpR->left, lpR->top, lpR->right, lpR->bottom);
|
|
AfxMessageBox(csData, MB_OK | MB_ICONINFORMATION);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CStatusDlg message handlers
|
|
|
|
BOOL CStatusDlg::OnInitDialog()
|
|
{
|
|
//Retrieve the Window Position from the registry
|
|
CWinApp* pApp = AfxGetApp();
|
|
m_WindowPos.left = pApp->GetProfileInt(_T("StatusDlg"), _T("left pos"), 100);
|
|
m_WindowPos.top = pApp->GetProfileInt(_T("StatusDlg"), _T("top pos"), 100);
|
|
|
|
// Set the window position
|
|
SetWindowPos( &wndBottom, m_WindowPos.left, m_WindowPos.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
|
|
|
|
BOOL bResult = CDialog::OnInitDialog();
|
|
|
|
// Sets the virtual size of the list box
|
|
m_Status.SetHorizontalExtent(2000);
|
|
|
|
// Allocates system memory to listbox to speed up memory allocations
|
|
m_Status.InitStorage(32000, 1048576);
|
|
|
|
if (m_hidden)
|
|
{
|
|
if (::IsWindow(m_hWnd))
|
|
ShowWindow(SW_HIDE);
|
|
}
|
|
else
|
|
{
|
|
if (::IsWindow(m_hWnd))
|
|
ShowWindow(SW_SHOW);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// This is called by the BaseDialog to create this Status Dialog
|
|
BOOL CStatusDlg::Create(CWnd* pParentWnd)
|
|
{
|
|
return CDialog::Create(IDD, pParentWnd);
|
|
}
|
|
|
|
// This tracks the window's position
|
|
void CStatusDlg::OnMove(int x, int y)
|
|
{
|
|
CDialog::OnMove(x, y);
|
|
|
|
GetWindowRect(&m_WindowPos);
|
|
}
|
|
|
|
void CStatusDlg::OnDestroy()
|
|
{
|
|
//Save the current window position
|
|
CWinApp* pApp = AfxGetApp();
|
|
pApp->WriteProfileInt(_T("StatusDlg"), _T("left pos"), m_WindowPos.left);
|
|
pApp->WriteProfileInt(_T("StatusDlg"), _T("top pos"), m_WindowPos.top);
|
|
|
|
CDialog::OnDestroy();
|
|
}
|