828 lines
14 KiB
C++
828 lines
14 KiB
C++
/*++
|
|
|
|
Copyright (c) 1994-1998 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
machine.cpp
|
|
|
|
Abstract:
|
|
|
|
IIS Machine properties page
|
|
|
|
Author:
|
|
|
|
Ronald Meijer (ronaldm)
|
|
|
|
Project:
|
|
|
|
Internet Services Manager
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
//
|
|
// Include Files
|
|
//
|
|
#include "stdafx.h"
|
|
#include "comprop.h"
|
|
#include "mime.h"
|
|
|
|
#define DLL_BASED __declspec(dllimport)
|
|
|
|
#include "mmc.h"
|
|
#include "machine.h"
|
|
|
|
#include "inetprop.h"
|
|
|
|
#include "..\mmc\constr.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
IMPLEMENT_DYNCREATE(CIISMachinePage, CPropertyPage)
|
|
|
|
|
|
|
|
typedef struct tagMASTER_DLL
|
|
{
|
|
LPCTSTR lpszDllName;
|
|
UINT nID;
|
|
} MASTER_DLL;
|
|
|
|
|
|
|
|
MASTER_DLL rgMasters[] =
|
|
{
|
|
//
|
|
// Note: path should not be neccesary for these
|
|
// config DLLs, because they should really already
|
|
// be loaded by inetmgr at this point.
|
|
//
|
|
{ _T("W3SCFG.DLL"), IDS_WWW_MASTER },
|
|
{ _T("FSCFG.DLL"), IDS_FTP_MASTER },
|
|
};
|
|
|
|
|
|
#define NUM_MASTER_DLL ARRAY_SIZE(rgMasters)
|
|
|
|
|
|
CMasterDll::CMasterDll(
|
|
IN UINT nID,
|
|
IN LPCTSTR lpszDllName,
|
|
IN LPCTSTR lpszMachineName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Construct master dll object
|
|
|
|
Arguments:
|
|
|
|
UINT nID : Resource ID
|
|
LPCTSTR lpszDllName : Dll filename and path
|
|
LPCTSTR lpszMachineName : Current machine name
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
: m_hDll(NULL),
|
|
m_pfnConfig(NULL),
|
|
m_strText()
|
|
{
|
|
m_hDll = ::AfxLoadLibrary(lpszDllName);
|
|
if (m_hDll != NULL)
|
|
{
|
|
//
|
|
// Check to see if this service is installed
|
|
//
|
|
pfnQueryServerInfo pfnInfo = (pfnQueryServerInfo)
|
|
::GetProcAddress(m_hDll, SZ_SERVERINFO_PROC);
|
|
|
|
if (pfnInfo != NULL)
|
|
{
|
|
ISMSERVERINFO ism;
|
|
ism.dwSize = ISMSERVERINFO_SIZE;
|
|
CError err((*pfnInfo)(lpszMachineName, &ism));
|
|
if (err.Succeeded())
|
|
{
|
|
m_pfnConfig = (pfnConfigure)::GetProcAddress(
|
|
m_hDll,
|
|
SZ_CONFIGURE_PROC
|
|
);
|
|
|
|
if (m_pfnConfig != NULL)
|
|
{
|
|
HINSTANCE hOld = AfxGetResourceHandle();
|
|
AfxSetResourceHandle(GetModuleHandle(COMPROP_DLL_NAME));
|
|
VERIFY(m_strText.LoadString(nID));
|
|
AfxSetResourceHandle(hOld);
|
|
|
|
//
|
|
// Success!
|
|
//
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Library didn't exist, was bogus, or unable to provide information
|
|
// about itself.
|
|
//
|
|
SAFE_AFXFREELIBRARY(m_hDll);
|
|
}
|
|
|
|
|
|
CMasterDll::~CMasterDll()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destructor -- decrement library reference count
|
|
|
|
Arguments:
|
|
|
|
N/A
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
{
|
|
TRACEEOLID("Deleting: " << m_strText);
|
|
SAFE_AFXFREELIBRARY(m_hDll);
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
void
|
|
CIISMachinePage::ParseMaxNetworkUse(
|
|
IN OUT CILong & nMaxNetworkUse,
|
|
OUT BOOL & fLimitNetworkUse
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Break out max network use function
|
|
|
|
Arguments:
|
|
|
|
CILong & nMaxNetworkUse : Maximum network value (will be changed)
|
|
BOOL & fLimitMaxNetworkUse : TRUE if max network is not infinite
|
|
|
|
Return Value
|
|
|
|
None/
|
|
|
|
--*/
|
|
{
|
|
fLimitNetworkUse = (nMaxNetworkUse != INFINITE_BANDWIDTH);
|
|
nMaxNetworkUse = fLimitNetworkUse
|
|
? (nMaxNetworkUse / KILOBYTE)
|
|
: (DEF_BANDWIDTH / KILOBYTE);
|
|
}
|
|
|
|
|
|
|
|
CIISMachinePage::CIISMachinePage(
|
|
IN LPCTSTR lpstrMachineName,
|
|
IN HINSTANCE hInstance
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Constructor for IIS Machine property page
|
|
|
|
Arguments:
|
|
|
|
LPCTSTR lpstrMachineName : Machine name
|
|
HINSTANCE hInstance : Instance handle
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
: CPropertyPage(CIISMachinePage::IDD),
|
|
m_strMachineName(lpstrMachineName),
|
|
m_fLocal(IsServerLocal(lpstrMachineName)),
|
|
m_ppropMimeTypes(NULL),
|
|
m_ppropMachine(NULL),
|
|
m_lstMasterDlls(),
|
|
m_hr(S_OK)
|
|
{
|
|
|
|
#if 0 // Keep class wizard happy
|
|
|
|
//{{AFX_DATA_INIT(CIISMachinePage)
|
|
m_fLimitNetworkUse = FALSE;
|
|
m_nMasterType = -1;
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_nMaxNetworkUse = 0;
|
|
|
|
#endif
|
|
|
|
m_nMasterType = 0;
|
|
|
|
//
|
|
// Data will be fetched later to prevent marshalling across
|
|
// threads errors. The dialog is constructed in one thread,
|
|
// and operates in another.
|
|
//
|
|
}
|
|
|
|
|
|
|
|
CIISMachinePage::~CIISMachinePage()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destructor
|
|
|
|
Arguments:
|
|
|
|
N/A
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
{
|
|
}
|
|
|
|
//
|
|
// COMPILER ISSUE::: Inlining this function doesn't
|
|
// work on x86 using NT 5!
|
|
//
|
|
HRESULT CIISMachinePage::QueryResult() const
|
|
{
|
|
return m_hr;
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CIISMachinePage::DoDataExchange(
|
|
IN CDataExchange * pDX
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialise/Store control data
|
|
|
|
Arguments:
|
|
|
|
CDataExchange * pDX - DDX/DDV control structure
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Make sure data was fetched
|
|
//
|
|
ASSERT(m_ppropMachine != NULL);
|
|
ASSERT(m_ppropMimeTypes != NULL);
|
|
|
|
CPropertyPage::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CIISMachinePage)
|
|
DDX_CBIndex(pDX, IDC_COMBO_MASTER_TYPE, m_nMasterType);
|
|
DDX_Control(pDX, IDC_EDIT_MAX_NETWORK_USE, m_edit_MaxNetworkUse);
|
|
DDX_Control(pDX, IDC_STATIC_THROTTLE_PROMPT, m_static_ThrottlePrompt);
|
|
DDX_Control(pDX, IDC_STATIC_MAX_NETWORK_USE, m_static_MaxNetworkUse);
|
|
DDX_Control(pDX, IDC_STATIC_KBS, m_static_KBS);
|
|
DDX_Control(pDX, IDC_BUTTON_EDIT_DEFAULT, m_button_EditDefault);
|
|
DDX_Control(pDX, IDC_CHECK_LIMIT_NETWORK_USE, m_check_LimitNetworkUse);
|
|
DDX_Control(pDX, IDC_COMBO_MASTER_TYPE, m_combo_MasterType);
|
|
DDX_Check(pDX, IDC_CHECK_LIMIT_NETWORK_USE, m_fLimitNetworkUse);
|
|
//}}AFX_DATA_MAP
|
|
if (m_edit_MaxNetworkUse.IsWindowEnabled())
|
|
{
|
|
DDX_Text(pDX, IDC_EDIT_MAX_NETWORK_USE, m_nMaxNetworkUse);
|
|
DDV_MinMaxLong(pDX, m_nMaxNetworkUse, 1, UD_MAXVAL);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Message Map
|
|
//
|
|
BEGIN_MESSAGE_MAP(CIISMachinePage, CPropertyPage)
|
|
//{{AFX_MSG_MAP(CIISMachinePage)
|
|
ON_BN_CLICKED(IDC_CHECK_LIMIT_NETWORK_USE, OnCheckLimitNetworkUse)
|
|
ON_BN_CLICKED(IDC_BUTTON_EDIT_DEFAULT, OnButtonEditDefault)
|
|
ON_BN_CLICKED(IDC_BUTTON_FILE_TYPES, OnButtonFileTypes)
|
|
ON_COMMAND(ID_HELP, OnHelp)
|
|
ON_COMMAND(ID_CONTEXT_HELP, OnHelp)
|
|
ON_WM_DESTROY()
|
|
ON_WM_HELPINFO()
|
|
//}}AFX_MSG_MAP
|
|
|
|
ON_EN_CHANGE(IDC_EDIT_MAX_NETWORK_USE, OnItemChanged)
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
BOOL
|
|
CIISMachinePage::SetControlStates()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set button states depending on contents of the controls.
|
|
Return whether or not "Limit network use" is on.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
TRUE if "Limit network use" is checked
|
|
|
|
--*/
|
|
{
|
|
BOOL fLimitOn = m_check_LimitNetworkUse.GetCheck() > 0;
|
|
|
|
m_static_MaxNetworkUse.EnableWindow(fLimitOn);
|
|
m_static_ThrottlePrompt.EnableWindow(fLimitOn);
|
|
m_edit_MaxNetworkUse.EnableWindow(fLimitOn);
|
|
m_static_KBS.EnableWindow(fLimitOn);
|
|
|
|
return fLimitOn;
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CIISMachinePage::LoadDelayedValues()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Load the metabase parameters
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Fetch the properties from the metabase
|
|
//
|
|
ASSERT(m_ppropMachine == NULL);
|
|
ASSERT(m_ppropMimeTypes == NULL);
|
|
|
|
//
|
|
// Share interface between the objects here
|
|
//
|
|
m_ppropMachine = new CMachineProps(m_strMachineName);
|
|
if (NULL == m_ppropMachine)
|
|
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
|
|
else if (FAILED(m_ppropMachine->QueryResult()))
|
|
return m_ppropMachine->QueryResult();
|
|
|
|
m_ppropMimeTypes = new CMimeTypes(m_ppropMachine);
|
|
if (NULL == m_ppropMimeTypes)
|
|
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
|
|
else if (FAILED(m_ppropMimeTypes->QueryResult()))
|
|
return m_ppropMimeTypes->QueryResult();
|
|
|
|
m_hr = m_ppropMachine->LoadData();
|
|
if (SUCCEEDED(m_hr))
|
|
{
|
|
m_nMaxNetworkUse = m_ppropMachine->m_nMaxNetworkUse;
|
|
ParseMaxNetworkUse(m_nMaxNetworkUse, m_fLimitNetworkUse);
|
|
|
|
m_hr = m_ppropMimeTypes->LoadData();
|
|
if (SUCCEEDED(m_hr))
|
|
{
|
|
m_strlMimeTypes = m_ppropMimeTypes->m_strlMimeTypes;
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Message Handlers
|
|
//
|
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
|
|
|
|
|
|
void
|
|
CIISMachinePage::OnHelp()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
'Help' button handler
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (m_strHelpFile.IsEmpty())
|
|
{
|
|
CRMCRegKey rk(REG_KEY, SZ_PARAMETERS, KEY_READ);
|
|
rk.QueryValue(SZ_HELPPATH, m_strHelpFile, EXPANSION_ON);
|
|
m_strHelpFile += _T("\\inetmgr.hlp");
|
|
TRACEEOLID("Initialized help file " << m_strHelpFile);
|
|
}
|
|
|
|
CWnd * pWnd = ::AfxGetMainWnd();
|
|
HWND hWndParent = pWnd != NULL
|
|
? pWnd->m_hWnd
|
|
: NULL;
|
|
|
|
::WinHelp(m_hWnd, m_strHelpFile, HELP_CONTEXT, HIDD_IIS_MACHINE);
|
|
}
|
|
|
|
BOOL
|
|
CIISMachinePage::OnHelpInfo(HELPINFO * pHelpInfo)
|
|
{
|
|
OnHelp();
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
CIISMachinePage::OnCheckLimitNetworkUse()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The "limit network use" checkbox has been clicked
|
|
Enable/disable the "max network use" controls.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (SetControlStates())
|
|
{
|
|
m_edit_MaxNetworkUse.SetSel(0,-1);
|
|
m_edit_MaxNetworkUse.SetFocus();
|
|
}
|
|
|
|
OnItemChanged();
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CIISMachinePage::OnItemChanged()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
All EN_CHANGE messages map to this function
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
SetModified(TRUE);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CIISMachinePage::OnButtonEditDefault()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
'edit default' button handler
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Get selection, and convert to index into server table
|
|
// via associative array.
|
|
//
|
|
CError err;
|
|
|
|
int nSel = m_combo_MasterType.GetCurSel();
|
|
ASSERT(nSel >= 0 && nSel < NUM_MASTER_DLL);
|
|
|
|
POSITION pos = m_lstMasterDlls.FindIndex(nSel);
|
|
ASSERT(pos != NULL);
|
|
|
|
CMasterDll * pDll = m_lstMasterDlls.GetAt(pos);
|
|
|
|
ASSERT(pDll != NULL);
|
|
|
|
//
|
|
// Allocate string with 2 terminating NULLS
|
|
//
|
|
int nLen = m_strMachineName.GetLength();
|
|
LPTSTR lpServers = AllocTString(nLen + 2);
|
|
if (lpServers == NULL)
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
::lstrcpy(lpServers, m_strMachineName);
|
|
lpServers[nLen + 1] = _T('\0');
|
|
|
|
err = pDll->Config(m_hWnd, lpServers);
|
|
}
|
|
|
|
SAFE_FREEMEM(lpServers);
|
|
err.MessageBoxOnFailure();
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CIISMachinePage::OnButtonFileTypes()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
'file types' button handler - bring up mime types dialog.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
HINSTANCE hOld = AfxGetResourceHandle();
|
|
AfxSetResourceHandle(GetModuleHandle(COMPROP_DLL_NAME));
|
|
|
|
CMimeDlg dlg(m_strlMimeTypes, this);
|
|
if (dlg.DoModal() == IDOK)
|
|
{
|
|
OnItemChanged();
|
|
}
|
|
|
|
AfxSetResourceHandle(hOld);
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
CIISMachinePage::OnInitDialog()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
WM_INITDIALOG handler. Initialize the dialog.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE if no focus is to be set automatically, FALSE if the focus
|
|
is already set.
|
|
|
|
--*/
|
|
{
|
|
CServerCapabilities caps(m_strMachineName, SZ_MBN_WEB);
|
|
BOOL fHasThrottling = caps.HasBwThrottling();
|
|
|
|
CError err(LoadDelayedValues());
|
|
|
|
if (err.Failed())
|
|
{
|
|
fHasThrottling = FALSE;
|
|
}
|
|
|
|
CPropertyPage::OnInitDialog();
|
|
|
|
//
|
|
// Fill the master combo box
|
|
//
|
|
int cServices = 0;
|
|
CMasterDll * pDll;
|
|
for (int n = 0; n < NUM_MASTER_DLL; ++n)
|
|
{
|
|
pDll = new CMasterDll(
|
|
rgMasters[n].nID,
|
|
rgMasters[n].lpszDllName,
|
|
m_strMachineName
|
|
);
|
|
|
|
if (pDll == NULL)
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
if (pDll->IsLoaded())
|
|
{
|
|
m_combo_MasterType.AddString(*pDll);
|
|
m_lstMasterDlls.AddTail(pDll);
|
|
++cServices;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Dll didn't load, toss it.
|
|
//
|
|
delete pDll;
|
|
}
|
|
}
|
|
|
|
if (cServices == 0)
|
|
{
|
|
//
|
|
// No master-programmable services installed, so disallow
|
|
// master editing.
|
|
//
|
|
GetDlgItem(IDC_BUTTON_EDIT_DEFAULT)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_GROUP_MASTER)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_STATIC_MASTER_PROMPT1)->EnableWindow(FALSE);
|
|
GetDlgItem(IDC_STATIC_MASTER_PROMPT2)->EnableWindow(FALSE);
|
|
m_combo_MasterType.EnableWindow(FALSE);
|
|
}
|
|
|
|
m_check_LimitNetworkUse.EnableWindow(fHasThrottling);
|
|
|
|
m_combo_MasterType.SetCurSel(0);
|
|
|
|
SetControlStates();
|
|
|
|
err.MessageBoxOnFailure();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
CIISMachinePage::OnApply()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
'Apply' button handler. Called when OK or APPLY is pressed.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
TRUE to continue, FALSE otherwise
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Don't use m_nMaxNetworkUse, because it would
|
|
// alter the values on the screen when DDX happens next.
|
|
//
|
|
CILong nMaxNetworkUse = m_nMaxNetworkUse;
|
|
BuildMaxNetworkUse(nMaxNetworkUse, m_fLimitNetworkUse);
|
|
|
|
m_ppropMachine->m_nMaxNetworkUse = nMaxNetworkUse;
|
|
CError err(m_ppropMachine->WriteDirtyProps());
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
m_ppropMimeTypes->m_strlMimeTypes = m_strlMimeTypes;
|
|
err = m_ppropMimeTypes->WriteDirtyProps();
|
|
}
|
|
|
|
if (err.Succeeded())
|
|
{
|
|
return CPropertyPage::OnApply();
|
|
}
|
|
|
|
//
|
|
// Failed
|
|
//
|
|
err.MessageBox();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CIISMachinePage::OnDestroy()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Window is being destroyed. Time to clean up
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ASSERT(m_ppropMachine != NULL);
|
|
ASSERT(m_ppropMimeTypes != NULL);
|
|
|
|
SAFE_DELETE(m_ppropMachine);
|
|
SAFE_DELETE(m_ppropMimeTypes);
|
|
|
|
while (!m_lstMasterDlls.IsEmpty())
|
|
{
|
|
CMasterDll * pDll = m_lstMasterDlls.RemoveHead();
|
|
delete pDll;
|
|
}
|
|
|
|
//
|
|
// Remove the help window if it's currently open
|
|
//
|
|
::WinHelp(m_hWnd, NULL, HELP_QUIT, 0L);
|
|
|
|
CPropertyPage::OnDestroy();
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CIISMachinePage::PostNcDestroy()
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
handle destruction of the window by freeing the this
|
|
pointer (as this modeless dialog must have been created
|
|
on the heap)
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
delete this;
|
|
}
|