// Error DemoView.cpp : implementation of the CErrorDemoView class
//

#include "stdafx.h"
#include "Error Demo.h"
#include "Error DemoDoc.h"
#include "Error DemoView.h"
#include "LocalErrors.h"
#include "ErrorMessage.h"
#include "WebDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CErrorDemoView

IMPLEMENT_DYNCREATE(CErrorDemoView, CView)

BEGIN_MESSAGE_MAP(CErrorDemoView, CView)
	//{{AFX_MSG_MAP(CErrorDemoView)
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(ID_SAMPLES_FLOATINGMENU, OnSamplesFloatingmenu)
	ON_COMMAND(ID_CONVENTIONAL_CRITICALERROR, OnConventionalCriticalerror)
	ON_COMMAND(ID_CONVENTIONAL_INFORMATION, OnConventionalInformation)
	ON_COMMAND(ID_CONVENTIONAL_SEVEREERROR, OnConventionalSevereerror)
	ON_COMMAND(ID_CONVENTIONAL_USERERROR, OnConventionalUsererror)
	ON_COMMAND(ID_FRIENDLY_CRITICALERROR, OnFriendlyCriticalerror)
	ON_COMMAND(ID_FRIENDLY_INFORMATION, OnFriendlyInformation)
	ON_COMMAND(ID_FRIENDLY_SEVEREERROR, OnFriendlySevereerror)
	ON_COMMAND(ID_FRIENDLY_USER_ERROR2, OnFriendlyUserError2)
	ON_COMMAND(ID_FRIENDLY_USERERROR, OnFriendlyUsererror)
	ON_COMMAND(ID_IMPROVED_CRITICALERROR, OnImprovedCriticalerror)
	ON_COMMAND(ID_IMPROVED_INFORMATION, OnImprovedInformation)
	ON_COMMAND(ID_IMPROVED_SEVEREERROR, OnImprovedSevereerror)
	ON_COMMAND(ID_IMPROVED_USERERROR, OnImprovedUsererror)
	ON_COMMAND(ID_SAMPLES_NERDOGRAM, OnSamplesNerdogram)
	ON_COMMAND(ID_TIMEOUT_INFORMATION, OnTimeoutInformation)
	ON_COMMAND(ID_TIMEOUT_POPUP, OnTimeoutPopup)
	ON_COMMAND(ID_TIMEOUT_RETRY, OnTimeoutRetry)
	ON_COMMAND(ID_TIMEOUT_USERERROR, OnTimeoutUsererror)
	ON_COMMAND(ID_TIMEOUT_USERERROR_2, OnTimeoutUsererror2)
	ON_COMMAND(IDM_POPUP, OnPopup)
	ON_COMMAND(IDS_STAGE_INIT, OnStageInit)
	ON_COMMAND(ID_EXPLORER_LOCAL, OnExplorerLocal)
	ON_COMMAND(ID_EXPLORER_ONLINE, OnExplorerOnline)
	ON_COMMAND(ID_ABOUT_AUTHOR, OnAboutAuthor)
	ON_COMMAND(ID_DIALOG_LOCAL, OnDialogLocal)
	ON_COMMAND(ID_DIALOG_ONLINE, OnDialogOnline)
	ON_COMMAND(IDM_CONFIGCHANGECANCELED, OnConfigchangecanceled)
	ON_COMMAND(IDM_CONFIGCHANGED, OnConfigchanged)
	ON_COMMAND(IDM_DEVICEARRIVAL, OnDevicearrival)
	ON_COMMAND(IDM_DEVICEQUERYREMOVE, OnDevicequeryremove)
	ON_COMMAND(IDM_DEVICEQUERYREMOVEFAILED, OnDevicequeryremovefailed)
	ON_COMMAND(IDM_DEVICEREMOVECOMPLETE, OnDeviceremovecomplete)
	ON_COMMAND(IDM_DEVICEREMOVEPENDING, OnDeviceremovepending)
	ON_COMMAND(IDM_DEVICETYPESPECIFIC, OnDevicetypespecific)
	ON_COMMAND(IDM_USERDEFINED, OnUserdefined)
	ON_COMMAND(IDM_QUERYCHANGECONFIG, OnQuerychangeconfig)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CErrorDemoView construction/destruction

CErrorDemoView::CErrorDemoView()
{
	DWORD	dwResult;

	// open (or create) a registry key where the error log path
	// and file name will be found ... use the app name to identify
	// the log location for this specific application only

	RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
					"Software\\Error Logs\\Error Demo",		// address of subkey name 
 					0,							// reserved 
					NULL,						// address of class string 
 					REG_OPTION_NON_VOLATILE,	// special options flag (default)
					KEY_ALL_ACCESS,				// desired security access 
					NULL,						// address of key security structure 
					&m_hAppKey,					// address of buffer for opened handle 
					&dwResult );				// address of disposition value buffer 
	if( dwResult == REG_CREATED_NEW_KEY )
	{
		DWORD	dwLen = _MAX_PATH;
		char    szDirPath[_MAX_PATH];
		CString csLogFile;

		// Because this is a new registry entry, we need to set
		// an error log path and file name entry

		GetCurrentDirectory( dwLen, (LPSTR) szDirPath );
		csLogFile = szDirPath;
		csLogFile += "\\Error Demo.LOG";
		RegSetValueEx( m_hAppKey,				// handle of key to set value for 
					   "Error Log Name",		// address of value to set 
					   0,						// reserved 
					   REG_SZ,					// flag for value type 
	  (BYTE *)(LPCTSTR)csLogFile,				// address of value data 
					   csLogFile.GetLength() );	// size of value data 
	}
}

CErrorDemoView::~CErrorDemoView()
{
	RegCloseKey( m_hAppKey );						// close the key, done with it
}

BOOL CErrorDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CErrorDemoView drawing

void CErrorDemoView::OnDraw(CDC* pDC)
{
	CErrorDemoDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CErrorDemoView printing

BOOL CErrorDemoView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CErrorDemoView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CErrorDemoView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CErrorDemoView diagnostics

#ifdef _DEBUG
void CErrorDemoView::AssertValid() const
{
	CView::AssertValid();
}

void CErrorDemoView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CErrorDemoDoc* CErrorDemoView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CErrorDemoDoc)));
	return (CErrorDemoDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CErrorDemoView message handlers

//== Information ============================================================

void CErrorDemoView::OnConventionalInformation() 
{
	CString csMsg;
	
	csMsg.LoadString( ID_CONVENTIONAL_INFORMATION_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnImprovedInformation() 
{
	CString csMsg;
	
	csMsg.LoadString( ID_IMPROVED_INFORMATION_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnFriendlyInformation() 
{
	CString csCaptions = "Actions taken:|Results:|May we recommend:|";

	m_cErrMsg.csErrorString.LoadString( ID_FRIENDLY_INFORMATION_MESSAGE );
	m_cErrMsg.nErrorCode = ID_FRIENDLY_INFORMATION_MESSAGE;
	m_cErrMsg.ErrorType = INFORMATION;
	ReportErrorStd( m_hAppKey, m_cErrMsg, 0, csCaptions );
}

void CErrorDemoView::OnTimeoutInformation() 
{
	int nTime = 45;
	CString csCaptions = "Actions taken:|Results:|May we recommend:|";

	m_cErrMsg.csErrorString.LoadString( ID_TIMEOUT_INFORMATION_MESSAGE );
	m_cErrMsg.csErrorString.Format( m_cErrMsg.csErrorString, nTime );
	m_cErrMsg.nErrorCode = ID_TIMEOUT_INFORMATION_MESSAGE;
	m_cErrMsg.ErrorType = INFORMATION;
	ReportErrorStd( m_hAppKey, m_cErrMsg, nTime, csCaptions );
}

//== User Errors ============================================================

void CErrorDemoView::OnConventionalUsererror() 
{
	CString csMsg;
	
	csMsg.LoadString( ID_CONVENTIONAL_USERERROR_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnImprovedUsererror() 
{
	CString	csMsg;

	csMsg.LoadString( ID_IMPROVED_USERERROR_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnFriendlyUsererror() 
{
	CString	csCaptions;
		
	csCaptions.LoadString( IDS_CAPTION_USERERROR );
	m_cErrMsg.csErrorString.LoadString( ID_FRIENDLY_USER_ERROR );
	m_cErrMsg.nErrorCode = ID_FRIENDLY_USER_ERROR;
	m_cErrMsg.ErrorType = USER_ERROR;
	ReportErrorStd( m_hAppKey, m_cErrMsg, 0, csCaptions );
}

void CErrorDemoView::OnFriendlyUserError2() 
{
	m_cErrMsg.csErrorString.LoadString( ID_FRIENDLY_USERERROR_MESSAGE_2 );
	m_cErrMsg.nErrorCode = ID_FRIENDLY_USERERROR_MESSAGE_2;
	m_cErrMsg.ErrorType = USER_ERROR;
	ReportErrorStd( m_hAppKey, m_cErrMsg, 0 );
}

void CErrorDemoView::OnTimeoutUsererror() 
{
	int		nTime = 45;
	CString	csCaptions;
		
	csCaptions.LoadString( IDS_CAPTION_USERERROR );
	m_cErrMsg.csErrorString.LoadString( ID_TIMEOUT_USER_ERROR );
	m_cErrMsg.csErrorString.Format( m_cErrMsg.csErrorString, nTime );
	m_cErrMsg.nErrorCode = ID_TIMEOUT_USER_ERROR;
	m_cErrMsg.ErrorType = USER_ERROR;
	ReportErrorStd( m_hAppKey, m_cErrMsg, nTime, csCaptions );
}

void CErrorDemoView::OnTimeoutUsererror2() 
{
	int		nTime = 15;
		
	m_cErrMsg.csErrorString.LoadString( ID_FRIENDLY_USERERROR_MESSAGE_2 );
	m_cErrMsg.nErrorCode = ID_FRIENDLY_USERERROR_MESSAGE_2;
	m_cErrMsg.ErrorType = USER_ERROR;
	ReportErrorStd( m_hAppKey, m_cErrMsg, nTime );
}

//== Non-Critical Errors =========================================================

void CErrorDemoView::OnConventionalCriticalerror() 
{
	CString csMsg;
	
	csMsg.LoadString( ID_CONVENTIONAL_CRITICALERROR_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnImprovedCriticalerror() 
{
	CString	csMsg;

	csMsg.LoadString( ID_IMPROVED_CRITICALERROR_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnFriendlyCriticalerror() 
{
	CString	csCaptions;
		
	csCaptions.LoadString( IDS_CAPTION_USERERROR );
	m_cErrMsg.csErrorString.LoadString( IDS_FRIENDLY_NONCRITICAL_ERROR_MESSAGE );
	m_cErrMsg.nErrorCode = IDS_FRIENDLY_NONCRITICAL_ERROR_MESSAGE;
	m_cErrMsg.ErrorType = NON_CRITICAL;
	ReportErrorStd( m_hAppKey, m_cErrMsg, 0, csCaptions );
}

//== Severe Errors ============================================================

void CErrorDemoView::OnConventionalSevereerror() 
{
	CString csMsg;
	
	csMsg.LoadString( ID_CONVENTIONAL_SEVEREERROR_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnImprovedSevereerror() 
{
	CString	csMsg;

	csMsg.LoadString( ID_IMPROVED_SEVEREERROR_MESSAGE );
	AfxMessageBox( csMsg );
}

void CErrorDemoView::OnFriendlySevereerror() 
{
	m_cErrMsg.csErrorString.LoadString( IDS_FRIENDLY_SEVERE_ERROR_MESSAGE );
	m_cErrMsg.nErrorCode = IDS_FRIENDLY_SEVERE_ERROR_MESSAGE;
	m_cErrMsg.ErrorType = SEVERE_ERROR;
	ReportErrorStd( m_hAppKey, m_cErrMsg );
}

//=== Retry Errors ==============================================================

void CErrorDemoView::OnTimeoutRetry() 
{
	int nTime = 45;
	CString csCaptions = "Failure Condition:||Correction Required:||";
	CString csTitle = "General Sonambulance Alert";

	m_cErrMsg.csErrorString.LoadString( ID_TIMEOUT_COFFEEPOTEMPTY );
	m_cErrMsg.nErrorCode = ID_TIMEOUT_COFFEEPOTEMPTY;
	m_cErrMsg.ErrorType = RETRY_ERROR;
	while( ReportErrorStd( m_hAppKey, m_cErrMsg, nTime, csCaptions, csTitle ) == IDOK )
	{
		Sleep( 5000 );		// this will retry until cancelled
	}
}

void CErrorDemoView::OnTimeoutPopup() 
{
	CPoint	cPoint;
	CRect		cRect;

	GetClientRect( cRect );
	ClientToScreen( cRect );
	cPoint.x = cRect.left + cRect.Width() / 2;
	cPoint.y = cRect.top + cRect.Height() / 2;
	m_cErrMsg.csErrorString.LoadString( IDS_POPUP_TIMEOUT );
	m_cErrMsg.nErrorCode = IDS_POPUP_TIMEOUT;
	m_cErrMsg.ErrorType = POPUP_MESSAGE;
	ReportPopup( m_cErrMsg, 15, cPoint, POPUP_BOTTOM | POPUP_RIGHT );
}

//=== Miscellancous Error Messages ==============================================

void CErrorDemoView::OnStageInit() 
{
	CString csSolution;

	m_cErrMsg.csErrorString.LoadString( IDS_STAGE_INIT_FAILURE );
	csSolution.LoadString( IDS_CORRECT_STAGE );
	m_cErrMsg.csErrorString += csSolution;
	m_cErrMsg.nErrorCode = IDS_STAGE_INIT_FAILURE;
	m_cErrMsg.ErrorType = SEVERE_ERROR;
	ReportErrorStd( m_hAppKey, m_cErrMsg, 0 );
}

void CErrorDemoView::OnSamplesNerdogram() 
{
	CDialog cDlg( IDD_NERDOGRAM, NULL );
	cDlg.DoModal();
}

void CErrorDemoView::OnPopup() 
{
	CPoint	cPoint;
	CRect		cRect;

	GetClientRect( cRect );
	ClientToScreen( cRect );
	cPoint.x = cRect.left + cRect.Width() / 2;
	cPoint.y = cRect.top + cRect.Height() / 2;
	m_cErrMsg.csErrorString.LoadString( IDS_POPUP_MESSAGE );
	m_cErrMsg.nErrorCode = IDS_POPUP_MESSAGE;
	m_cErrMsg.ErrorType = POPUP_MESSAGE;
	ReportPopup( m_cErrMsg, 0, cPoint, POPUP_LEFT | POPUP_TOP );	
}

void CErrorDemoView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	PopupMenu( point );	
	CView::OnRButtonDown(nFlags, point);
}

void CErrorDemoView::OnSamplesFloatingmenu() 
{
	CPoint	cPoint;

	cPoint.x = 400;
	cPoint.y = 400;
	PopupMenu( cPoint );
}

void CErrorDemoView::PopupMenu( CPoint point )
{
	ClientToScreen( &point );
	m_pMenu = new CMenu();
	m_pMenu->CreatePopupMenu();
	m_pMenu->AppendMenu( MF_STRING, ID_SAMPLES_NERDOGRAM, "Nerd-o-gram" );
	m_pMenu->AppendMenu( MF_STRING, IDM_POPUP, "Popup window" );
	m_pMenu->AppendMenu( MF_STRING, ID_TIMEOUT_POPUP, "Popup with timeout" );
	m_pMenu->AppendMenu( MF_STRING, ID_FLOAT_01, "Disabled menu item" );
	m_pMenu->EnableMenuItem( ID_FLOAT_01, MF_GRAYED | MF_BYCOMMAND | MF_DISABLED );
	m_pMenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this );
}

//=== IE OCX as full client window ===

void CErrorDemoView::OnExplorerLocal() 
{
	CallExplorer( "file://C:\\SampleExp_page_001.html" );
	return;
}

void CErrorDemoView::OnExplorerOnline() 
{
	CallExplorer( "www.ezzell.org\\SampleExp_page_001.html" );
	return;
}

void CErrorDemoView::OnAboutAuthor() 
{
	CallExplorer( "www.ezzell.org" );
	return;
}

void CErrorDemoView::CallExplorer( CString csURL )
{
	CRect	rect;

	GetClientRect( &rect );
	m_pBrowser = new CWebBrowser2;
	ASSERT( m_pBrowser );
	if( !m_pBrowser->Create( NULL, NULL, WS_VISIBLE, rect, this, NULL ) )
	{
		TRACE( "Failed to create browser\n" );
		delete m_pBrowser;
		m_pBrowser = NULL;
		return;
	}
	COleVariant noArg;
	m_pBrowser->Navigate( csURL, &noArg, &noArg, &noArg, &noArg );
	return;
}

//=== IE OCX in dialog window ===

void CErrorDemoView::OnDialogLocal() 
{
	CallWebDialog( "file:///C:\\SampleExp_page_001.html" ); 	
	// will also accept "file://C:\\..."
}

void CErrorDemoView::OnDialogOnline() 
{
	CallWebDialog( "www.ezzell.org\\SampleExp_page_001.html" ); 	
}

void CErrorDemoView::CallWebDialog( CString csURL ) 
{
	CWebDialog cDlg( NULL );

	cDlg.m_csURL = csURL;
	cDlg.DoModal();
}

void CErrorDemoView::OnConfigchangecanceled() 
{
	SimulatePnPMessage( IDS_CONFIGCHANGECANCELED );
}

void CErrorDemoView::OnConfigchanged() 
{
	SimulatePnPMessage( IDS_CONFIGCHANGED );
}

void CErrorDemoView::OnDevicearrival() 
{
	SimulatePnPMessage( IDS_DEVICEARRIVAL );	
}

void CErrorDemoView::OnDevicequeryremove() 
{
	SimulatePnPMessage( IDS_DEVICEQUERYREMOVE );	
}

void CErrorDemoView::OnDevicequeryremovefailed() 
{
	SimulatePnPMessage( IDS_DEVICEQUERYREMOVEFAILED );	
}

void CErrorDemoView::OnDeviceremovecomplete() 
{
	SimulatePnPMessage( IDS_DEVICEREMOVECOMPLETE );		
}

void CErrorDemoView::OnDeviceremovepending() 
{
	SimulatePnPMessage( IDS_DEVICEREMOVEPENDING );
}

void CErrorDemoView::OnDevicetypespecific() 
{
	SimulatePnPMessage( IDS_DEVICETYPESPECIFIC );	
}

void CErrorDemoView::OnQuerychangeconfig() 
{
	SimulatePnPMessage( IDS_QUERYCHANGECONFIG );	
}

void CErrorDemoView::OnUserdefined() 
{
	SimulatePnPMessage( IDS_USERDEFINED );	
}

void CErrorDemoView::SimulatePnPMessage( int nMsg )
{
	SimulatePnPMessage( nMsg, 0 );
}

void CErrorDemoView::SimulatePnPMessage( int nMsg, int nEvent )
{
	CString csSolution;
	CString csCaptions = "Simulated PnP message:|Event ID:|Interpretation:|";

	m_cErrMsg.csErrorString.LoadString( nMsg );
	m_cErrMsg.nErrorCode = nMsg;

	if( nEvent == 0 )
		m_cErrMsg.ErrorType = USER_ERROR;
	else
	{
		m_cErrMsg.csErrorString.Format( m_cErrMsg.csErrorString, nEvent );
		m_cErrMsg.ErrorType = INFORMATION;
	}
	ReportErrorStd( m_hAppKey, m_cErrMsg, 30, csCaptions );
}

BOOL CErrorDemoView::OnCommand(WPARAM wParam, LPARAM lParam) 
{
	int wmID, wmEvent, nMsg;

	wmID	= LOWORD( wParam );
	wmEvent	= HIWORD( wParam );
    switch( wmID )
	{
	    case WM_DEVICECHANGE:
			switch( wmEvent )
			{
				case DBT_CONFIGCHANGECANCELED:		
					nMsg = IDS_CONFIGCHANGECANCELED;	
					break;

				case DBT_CONFIGCHANGED:				
					nMsg = IDS_CONFIGCHANGED;			
					break;

				case DBT_DEVICEARRIVAL:				
					nMsg = IDS_DEVICEARRIVAL;			
					break;

				case DBT_DEVICEQUERYREMOVE:			
					nMsg = IDS_DEVICEQUERYREMOVE;		
					break;

				case DBT_DEVICEQUERYREMOVEFAILED:	
					nMsg = IDS_DEVICEQUERYREMOVEFAILED;	
					break;

				case DBT_DEVICEREMOVECOMPLETE:		
					nMsg = IDS_DEVICEREMOVECOMPLETE;	
					break;

				case DBT_DEVICEREMOVEPENDING:		
					nMsg = IDS_DEVICEREMOVEPENDING;		
					break;

				case DBT_DEVICETYPESPECIFIC:		
					nMsg = IDS_DEVICETYPESPECIFIC;		
					break;

				case DBT_QUERYCHANGECONFIG:			
					nMsg = IDS_QUERYCHANGECONFIG;		
					break;

				case DBT_USERDEFINED:				
					nMsg = IDS_USERDEFINED;				
					break;
			}
			break;
	}
	SimulatePnPMessage( nMsg, wmEvent );
	return CView::OnCommand(wParam, lParam);
}


