|
|
/*++
Copyright (c) 1994-2001 Microsoft Corporation
Module Name : errordlg.cpp
Abstract: Error edit dialog
Author: Ronald Meijer (ronaldm) Sergei Antonov (sergeia)
Project: Internet Services Manager
Revision History:
--*/ #include "stdafx.h"
#include "common.h"
#include "inetprop.h"
#include "InetMgrapp.h"
#include "shts.h"
#include "w3sht.h"
#include "resource.h"
#include "fltdlg.h"
#include "errordlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
//
// HTTP Custom Error Definition
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//
// Static Initialization
//
LPCTSTR CCustomError::s_szSep = _T(","); LPCTSTR CCustomError::s_szURL = _T("URL"); LPCTSTR CCustomError::s_szFile = _T("FILE"); LPCTSTR CCustomError::s_szNoSubError = _T("*");
#define GET_FIELD()\
end = strError.Find(s_szSep, start);\ if (end == -1) \ end = strError.GetLength() #define SKIP()\
start = end + skip #define GET_INT_FIELD(n)\
GET_FIELD();\ (n) = StrToInt(strError.Mid(start, end - start));\ SKIP()
/* static */ BOOL CCustomError::CrackErrorString( IN LPCTSTR lpstrErrorString, OUT UINT & nError, OUT UINT & nSubError, OUT ERT & nType, OUT CString & str ) /*++
Routine Description
Helper function to parse error string into component parts
Arguments:
LPCTSTR lpstrErrorString : Error input string UINT & nError : Error UINT & nSubError : Sub Error int & nType : Error type CString & str : Text parameter Return Value:
TRUE for success, FALSE for failure
--*/ { BOOL fSuccess = FALSE;
do { CString strError(lpstrErrorString); TRACEEOLID(strError);
int start = 0, end, skip = lstrlen(s_szSep);
GET_INT_FIELD(nError); ASSERT(nError > 0); GET_INT_FIELD(nSubError); GET_FIELD(); nType = strError.Mid(start, end - start).CompareNoCase(s_szURL) == 0 ? ERT_URL : ERT_FILE; SKIP(); if (-1 != (end = strError.ReverseFind((TCHAR) s_szSep))) str = strError.Mid(start, end - start); else str = strError.Right(strError.GetLength() - start); fSuccess = TRUE; } while(FALSE);
return fSuccess; }
/* static */ void CCustomError::CrackErrorDescription( IN LPCTSTR lpstrErrorString, OUT UINT & nError, OUT UINT & nSubError, OUT BOOL & fURLSupported, OUT CString & str ) /*++
Routine Description
Helper function to parse error description into component parts
Arguments:
LPCTSTR lpstrErrorString : Error input string UINT & nError : Error UINT & nSubError : Sub Error BOOL & fURLSupported : Return TRUE if urls are allowed CString & str : Text parameter Return Value:
None.
--*/ { try { CString strError(lpstrErrorString); TRACEEOLID(strError);
int start = 0, end, skip = lstrlen(s_szSep); fURLSupported = FALSE;
do { GET_INT_FIELD(nError); ASSERT(nError > 0); GET_INT_FIELD(nSubError); GET_FIELD(); str = strError.Mid(start, end - start); SKIP(); GET_FIELD(); if (nSubError > 0) { str += _T(" - "); str += strError.Mid(start, end - start); } SKIP(); GET_FIELD(); fURLSupported = end != -1 && end > start ? 0 == StrToInt(strError.Mid(start, end - start)) : FALSE; } while (FALSE); /*
LPTSTR lp = strError.GetBuffer(0); LPTSTR lpField = StringTok(lp, s_szSep); nError = _ttoi(lpField); ASSERT(nError > 0); lpField = StringTok(NULL, s_szSep); ASSERT(lpField != NULL); nSubError = lpField != NULL ? _ttoi(lpField) : 0; lpField = StringTok(NULL, s_szSep); ASSERT(lpField != NULL); str = lpField; lpField = StringTok(NULL, s_szSep); ASSERT(lpField != NULL); if (nSubError > 0) { //
// Add sub error text
//
ASSERT(nSubError > 0); str += _T(" - "); str += lpField; lpField = StringTok(NULL, s_szSep); }
ASSERT(lpField != NULL); fURLSupported = lpField != NULL ? (_ttoi(lpField) == 0) : FALSE; */ } catch(CException * e) { e->ReportError(); e->Delete(); } }
CCustomError::CCustomError( IN LPCTSTR lpstrErrorString ) /*++
Routine Description:
Construct error definition from metabase string Arguments:
LPCTSTR lpstrErrorString : Error string Return Value:
N/A
--*/ : m_nType(ERT_DEFAULT) { CrackErrorDescription( lpstrErrorString, m_nError, m_nSubError, m_fURLSupported, m_strDefault ); }
void CCustomError::BuildErrorString( OUT CString & str ) /*++
Routine Description:
Build metabase-ready error string out of the current values
Arguments:
CString & str : String
Return Value:
None
--*/ { ASSERT(!IsDefault());
try { if (m_nSubError > 0) { str.Format(_T("%d,%d,%s,%s"), m_nError, m_nSubError, IsFile() ? s_szFile : s_szURL, (LPCTSTR)m_str ); } else { str.Format( _T("%d,%s,%s,%s"), m_nError, s_szNoSubError, IsFile() ? s_szFile : s_szURL, (LPCTSTR)m_str ); } } catch(CMemoryException * e) { e->ReportError(); e->Delete(); } }
int CCustomError::OrderByErrorNum( IN const CObjectPlus * pobAccess ) const /*++
Routine Description:
Compare two custom errors against each other, and sort on Number first, and order secondarily.
Arguments:
const CObjectPlus * pobAccess : This really refers to another CCustomError to be compared to.
Return Value:
Sort (+1, 0, -1) return value
--*/ { const CCustomError * pob = (CCustomError *)pobAccess;
if (pob->m_nError != m_nError) { // sort by error in small to big order
return m_nError - pob->m_nError; }
//
// Sort by sub error in small to big order
//
return m_nSubError - pob->m_nSubError; }
//
// Custom Errors property page
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CCustomErrorDlg::CCustomErrorDlg( IN OUT CCustomError * pErr, IN BOOL fLocal, IN CWnd * pParent OPTIONAL ) /*++
Routine Description:
Error editing dialog
Arguments:
CCustomError * pErr : Error definition to be edited BOOL fLocal : TRUE if the current computer is local CWnd * pParent : Optional parent window or NULL
Return Value:
N/A
--*/ : CDialog(CCustomErrorDlg::IDD, pParent), m_fLocal(fLocal), m_pErr(pErr), m_nMessageType(pErr->m_nType), m_strTextFile(pErr->m_str), m_strDefText(pErr->m_strDefault) { #if 0 // Keep Class Wizard Happy
//{{AFX_DATA_INIT(CCustomErrorDlg)
m_nMessageType = -1; m_strTextFile = _T(""); m_strDefText = _T(""); //}}AFX_DATA_INIT
#endif // 0
VERIFY(m_strFile.LoadString(IDS_FILE_PROMPT)); VERIFY(m_strURL.LoadString(IDS_URL_PROMPT)); }
void CCustomErrorDlg::DoDataExchange( IN CDataExchange * pDX ) /*++
Routine Description:
Initialise/Store control data
Arguments:
CDataExchange * pDX - DDX/DDV control structure
Return Value:
None
--*/ { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CCustomErrorDlg)
DDX_CBIndex(pDX, IDC_COMBO_MESSAGE_TYPE, m_nMessageType); DDX_Text(pDX, IDC_STATIC_DEF_TEXT, m_strDefText); DDX_Control(pDX, IDC_EDIT_TEXT_FILE, m_edit_TextFile); DDX_Control(pDX, IDC_STATIC_SUB_PROMPT, m_static_SubErrorPrompt); DDX_Control(pDX, IDC_STATIC_SUB_ERROR_CODE, m_static_SubError); DDX_Control(pDX, IDC_STATIC_TEXT_FILE_PROMT, m_static_TextFilePrompt); DDX_Control(pDX, IDC_BUTTON_BROWSE, m_button_Browse); DDX_Control(pDX, IDC_COMBO_MESSAGE_TYPE, m_combo_MessageType); DDX_Control(pDX, IDOK, m_button_OK); //}}AFX_DATA_MAP
DDX_TextBalloon(pDX, IDC_STATIC_ERROR_CODE, m_pErr->m_nError); DDX_TextBalloon(pDX, IDC_STATIC_SUB_ERROR_CODE, m_pErr->m_nSubError);
DDX_Text(pDX, IDC_EDIT_TEXT_FILE, m_strTextFile); m_strTextFile.TrimLeft(); m_strTextFile.TrimRight(); if (pDX->m_bSaveAndValidate) { if (m_nMessageType == CCustomError::ERT_FILE) { DDV_FilePath(pDX, m_strTextFile, m_fLocal); } else if (m_nMessageType == CCustomError::ERT_URL) { // We are accepting only absolute URLs within the site, i.e. /foo/bar/error.html
if (!IsRelURLPath(m_strTextFile)) { pDX->PrepareEditCtrl(IDC_EDIT_TEXT_FILE); DDV_ShowBalloonAndFail(pDX, IDS_BAD_ERROR_URL); } } } }
//
// Message Map
//
BEGIN_MESSAGE_MAP(CCustomErrorDlg, CDialog) //{{AFX_MSG_MAP(CCustomErrorDlg)
ON_CBN_SELCHANGE(IDC_COMBO_MESSAGE_TYPE, OnSelchangeComboMessageType) ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnButtonBrowse) ON_EN_CHANGE(IDC_EDIT_TEXT_FILE, OnChangeEditTextFile) //}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CCustomErrorDlg::SetControlStates() /*++
Routine Description:
Set the enabled states of the dialog controls depending on the current state of the dialog
Arguments:
None
Return Value:
TRUE if file/url is selected, FALSE otherwise
--*/ { int nCurSel = m_combo_MessageType.GetCurSel(); BOOL fFile = nCurSel == CCustomError::ERT_FILE; BOOL fDefault = nCurSel == CCustomError::ERT_DEFAULT; ActivateControl(m_button_Browse, m_fLocal && fFile);
ActivateControl(m_edit_TextFile, !fDefault); ActivateControl(m_static_TextFilePrompt, !fDefault); m_static_TextFilePrompt.SetWindowText(fFile ? m_strFile : m_strURL);
m_button_OK.EnableWindow(fDefault || m_edit_TextFile.GetWindowTextLength() > 0);
return !fDefault; }
//
// Message Handlers
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
BOOL CCustomErrorDlg::OnInitDialog() /*++
Routine Description:
WM_INITDIALOG handler. Initialize the dialog.
Arguments:
None.
Return Value:
TRUE if focus is to be set automatically, FALSE if the focus is already set.
--*/ { CDialog::OnInitDialog();
//
// Browsing available locally only
//
m_button_Browse.EnableWindow(m_fLocal);
CString str; VERIFY(str.LoadString(IDS_DEFAULT_ERROR)); m_combo_MessageType.AddString(str); VERIFY(str.LoadString(IDS_FILE)); m_combo_MessageType.AddString(str);
if (m_pErr->URLSupported() || m_nMessageType == CCustomError::ERT_URL) { VERIFY(str.LoadString(IDS_URL)); m_combo_MessageType.AddString(str); }
m_combo_MessageType.SetCurSel(m_nMessageType);
if (m_pErr->m_nSubError == 0) { DeActivateControl(m_static_SubErrorPrompt); DeActivateControl(m_static_SubError); }
SetControlStates(); // if (m_nMessageType == CCustomError::ERT_FILE)
// {
// #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
// LimitInputPath(CONTROL_HWND(IDC_EDIT_TEXT_FILE),TRUE);
// #else
// LimitInputPath(CONTROL_HWND(IDC_EDIT_TEXT_FILE),FALSE);
// #endif
// }
// else if (m_nMessageType == CCustomError::ERT_URL)
// {
// }
return TRUE; }
void CCustomErrorDlg::OnSelchangeComboMessageType() /*++
Routine Description:
Handle change in message type combo box
Arguments:
None
Return Value:
None
--*/ { int nSel = m_combo_MessageType.GetCurSel(); if (m_nMessageType == nSel) { //
// Selection didn't change
//
return; }
m_nMessageType = nSel;
if (SetControlStates()) { m_edit_TextFile.SetWindowText(_T("")); m_edit_TextFile.SetFocus(); } }
void CCustomErrorDlg::OnChangeEditTextFile() /*++
Routine Description:
Handle change in text/file edit box
Arguments:
None
Return Value:
None
--*/ { SetControlStates(); }
void CCustomErrorDlg::OnOK() /*++
Routine Description:
Handle the OK button being pressed
Arguments: None
Return Value:
None
--*/ { if (UpdateData(TRUE)) { m_pErr->m_nType = (CCustomError::ERT)m_nMessageType; m_pErr->m_str = m_strTextFile; CDialog::OnOK(); } }
void CCustomErrorDlg::OnButtonBrowse() /*++
Routine Description:
Browse for HTML File Arguments:
None Return Value:
None
--*/ { ASSERT(m_fLocal);
//
// popup the file dialog and let the user select the error htm file
//
CString str; str.LoadString(IDS_HTML_MASK); CFileDialog dlgBrowse(TRUE, NULL, NULL, OFN_HIDEREADONLY, str, this); // Disable hook to get Windows 2000 style dialog
dlgBrowse.m_ofn.Flags &= ~(OFN_ENABLEHOOK); dlgBrowse.m_ofn.Flags |= OFN_DONTADDTORECENT|OFN_FILEMUSTEXIST;
if (dlgBrowse.DoModal() == IDOK) { m_pErr->m_str = dlgBrowse.GetPathName(); m_edit_TextFile.SetWindowText(m_pErr->m_str); } }
|