Figure 3 CCustomAppWiz
class CCustomAppWiz : public CObject
{
public:
CMapStringToString m_Dictionary;
virtual void GetPlatforms(CStringList& rPlatforms) {}
virtual CAppWizStepDlg* Next(CAppWizStepDlg* pDlg)
{ return NULL; }
virtual CAppWizStepDlg* Back(CAppWizStepDlg* pDlg)
{ return NULL; }
virtual void InitCustomAppWiz() { m_Dictionary.RemoveAll(); }
virtual void ExitCustomAppWiz() {}
virtual LPCTSTR LoadTemplate(LPCTSTR lpszTemplateName,
DWORD& rdwSize, HINSTANCE hInstance = NULL);
virtual void CopyTemplate(LPCTSTR lpszInput,
DWORD dwSize,
OutputStream* pOutput);
virtual void ProcessTemplate(LPCTSTR lpszInput,
DWORD dwSize,
OutputStream* pOutput);
virtual void PostProcessTemplate(LPCTSTR szTemplate) {}
virtual void CustomizeProject(IBuildProject* pProject) {}
};
Figure 4 CDialogChooser
class CDialogChooser
{
public:
CDialogChooser();
~CDialogChooser();
// All calls by mfcapwz.dll to this AppWizard's Next
// and Back functions are delegated to these member
// functions. These functions keep track of what
// the current state of the AppWizard and which
// step we're on
CAppWizStepDlg* Next(CAppWizStepDlg* pDlg);
CAppWizStepDlg* Back(CAppWizStepDlg* pDlg);
protected:
// Current step's index into the current track
int m_nCurrDlg;
// Internal array of pointers to the steps
CAppWizStepDlg* m_pDlgs[LAST_DLG + 1];
// Current track
int m_nTrack;
};
Figure 5 Handling the Next Button
CAppWizStepDlg* CMyWizardAppWiz::Next(CAppWizStepDlg* pDlg)
{
// CMyWizardAppWizard is derived from
// Delegate to the dialog chooser
return m_pChooser->Next(pDlg);
}
CAppWizStepDlg* CDialogChooser::Next(CAppWizStepDlg* pDlg)
{
ASSERT(m_nTrack == 0 || m_nTrack == 1);
ASSERT(0 <= m_nCurrDlg && m_nCurrDlg < nLast[m_nTrack]);
ASSERT(pDlg == m_pDlgs[(pnTrack[m_nTrack])[m_nCurrDlg]]);
m_nCurrDlg++;
// If the new step is the "project type" step,
// don't display the max number
// of steps.
if (m_nCurrDlg == 1)
SetNumberOfSteps(-1);
return m_pDlgs[(pnTrack[m_nTrack])[m_nCurrDlg]];
}
Figure 6 Including Text Files as Text Resources
NEWPROJ.INF |
TEMPLATE DISCARDABLE |
"template\\newproj.inf" |
CONFIRM.INF |
TEMPLATE DISCARDABLE |
"template\\confirm.inf" |
README.TXT |
TEMPLATE DISCARDABLE |
"template\\ReadMe.txt" |
ROOT.ICO |
TEMPLATE DISCARDABLE |
"template\\res\\root.ico" |
ROOT.RC2 |
TEMPLATE DISCARDABLE |
"template\\res\\root.rc2" |
RESOURCE.H |
TEMPLATE DISCARDABLE |
"template\\resource.h" |
ROOT.CLW |
TEMPLATE DISCARDABLE |
"template\\root.clw" |
ROOT.CPP |
TEMPLATE DISCARDABLE |
"template\\root.cpp" |
ROOT.H |
TEMPLATE DISCARDABLE |
"template\\root.h" |
ROOT.RC |
TEMPLATE DISCARDABLE |
"template\\root.rc" |
DIALOG.CPP |
TEMPLATE DISCARDABLE |
"template\\Dialog.cpp" |
DIALOG.H |
TEMPLATE DISCARDABLE |
"template\\Dialog.h" |
STDAFX.CPP |
TEMPLATE DISCARDABLE |
"template\\StdAfx.cpp" |
STDAFX.H |
TEMPLATE DISCARDABLE |
"template\\StdAfx.h" |
Figure 7 Conditional Code Inclusion
$$IF (USEABOUT)
void C$$Safe_root$$Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
$$ENDIF
Figure 8 Handling OnDismiss
BOOL CCustom1Dlg::OnDismiss()
{
if (!UpdateData(TRUE))
return FALSE;
if (m_bUseAboutBox)
{
MyWizardaw.m_Dictionary[_T("ABOUTBOX")] = _T("1");
}
else
{
MyWizardaw.m_Dictionary.RemoveKey(_T("ABOUTBOX"));
}
return TRUE; // return FALSE if the dialog shouldn't be
// dismissed
}
Figure 9 The IBuildProject Interface
interface IBuildProject: IGenericProject
{
/* IUnknown methods Removed for clarity */
/* IDispatch methods Removed for clarity */
/* IGenericProject methods */
HRESULT get_Name(BSTR FAR* Name);
HRESULT get_FullName(BSTR FAR* Name);
HRESULT get_Application(IDispatch * FAR* Application);
HRESULT get_Parent(IDispatch * FAR* Parent);
HRESULT get_Type(BSTR FAR* pType);
HRESULT Reserved1();
HRESULT Reserved2();
HRESULT Reserved3();
HRESULT Reserved4();
HRESULT Reserved5();
HRESULT Reserved6();
HRESULT Reserved7();
HRESULT Reserved8();
HRESULT Reserved9();
HRESULT Reserved10();
/* IBuildProject Methods */
HRESULT get_Configurations(IConfigurations
FAR* FAR* Configs);
HRESULT AddFile(BSTR szFile, VARIANT Reserved);
HRESULT AddConfiguration(BSTR szConfig, VARIANT Reserved);
};
Figure 10 RTTI option switch
void CMyWizardAppWiz::CustomizeProject(IBuildProject* pProject)
{
// enumerate all build configurations
// and adds compiler/linker options.
// Requires including the "buildguid.h"
// file from VC\Include\Objects
IConfigurations* pConfigs = NULL;
pProject->get_Configurations(&pConfigs);
ASSERT(pConfigs);
CComPtr<IUnknown> pUnk;
CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
if (SUCCEEDED(pConfigs->get__NewEnum(&pUnk)) && pUnk != NULL)
{
pNewEnum = pUnk;
VARIANT varConfig;
VARIANT reserved;
VariantInit(&varConfig);
VariantInit(&reserved);
CComQIPtr<IConfiguration, &IID_IConfiguration> pConfig;
while (pNewEnum->Next(1, &varConfig, NULL) == S_OK)
{
ASSERT (varConfig.vt == VT_DISPATCH);
pConfig = varConfig.pdispVal;
VariantClear(&varConfig);
// add the RTTI option
CComBSTR bstrTool = "cl.exe";
CComBSTR bstrOption = "/GR";
pConfig->AddToolSettings(bstrTool,
bstrOption,
reserved);
}
}
if ( pConfigs )
pConfigs->Release();
}