// TippyDialog.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include <afxdllx.h>
#include "TippyDialog.h"
#include "TippyDialogaw.h"
#ifdef _PSEUDO_DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static AFX_EXTENSION_MODULE TippyDialogDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("TIPPYDIALOG.AWX Initializing!\n");
// Extension DLL one-time initialization
AfxInitExtensionModule(TippyDialogDLL, hInstance);
// Insert this DLL into the resource chain
new CDynLinkLibrary(TippyDialogDLL);
// Register this custom AppWizard with MFCAPWZ.DLL
SetCustomAppWizClass(&TippyDialogaw);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("TIPPYDIALOG.AWX Terminating!\n");
}
return 1; // ok
}
Figure 3 Helper Functions for Custom Wizards
Function |
Description |
GetDialog |
Find step dialog for a given wizard step number |
ScanForAvailableLanguages |
Identify languages supported by this wizard |
SetCustomAppWizClass |
Register wizard object with AppWizard |
SetNumberOfSteps |
Specify how many wizard steps will be presented |
SetSupportedLanguages |
Specify which languages will be supported for the current project |
Figure 4 CCustomAppWiz Virtual Functions
Function |
Description |
Back |
Get a pointer to the previous wizard step |
CopyTemplate |
Copy a binary template to a project file |
ExitCustomAppWiz |
Terminate use of the wizard object |
GetPlatforms |
Edit the list of platforms on which wizard's type of application can run |
InitCustomAppWiz |
Initialize the wizard object |
LoadTemplate |
Load the template resource used to generate a project file |
Next |
Get a pointer to the next wizard step |
PostProcessTemplate |
Deallocate memory used to hold a template resource |
ProcessTemplate |
Expand macro references in a template resource |
Figure 5 CAppWizStepDlg Virtual Functions
Function |
Description |
Create |
Override of CDialog::Create to control the default font |
OnDismiss |
Respond to user leaving this wizard step |
PreTranslateMessage |
Override of CDialog::PreTranslateMessage to handle tabbing from one step to another |
Figure 6 Standard Macros
Name |
Description |
Root root |
Project name, without file extension and spelled exactly as the user entered it. |
ROOT |
Same as root, but spelled in uppercase. |
Safe_root |
Project name in mixed case, but with all non-alphanumeric characters removed. |
safe_root |
You can use SAFE_ROOT as the name of a preprocessor or C/C++ symbol. |
SAFE_ROOT |
Same as safe_root, but in uppercase. |
FULL_DIR_PATH |
The full path name of the directory where the new project will be created, including a trailing backslash. |
TARGET_INTEL |
These values exist in the dictionary |
TARGET_MIPS |
if the programmer selected the |
TARGET_ALPHA |
corresponding target platform from |
TARGET_MAC |
the list of platforms in the New |
TARGET_68KMAC |
Project Workspace dialog. TARGET_ |
TARGET_POWERMAC |
INTEL corresponds to the Win32 choice. TARGET_MAC indicates that either TARGET_68KMAC or TARGET_POWERMAC was chosen. |
host_cpu |
Target CPU type (such as "X86"). |
cpu |
Target CPU in a different form (such as "i86"). |
platform_long |
Name of target platform (such as "Win32 (x86)"). |
platform_short |
Name of target platform (such as "Win32"). |
Figure 9 NEWPROJ.INF Template Resource
/res +MAINFRM.CPP MainFrm.cpp MAINFRM.H MainFrm.h +README.TXT ReadMe.txt RESOURCE.H Resource.h +STDAFX.CPP StdAfx.cpp STDAFX.H StdAfx.h ROOT.CLW $$root$$.clw +ROOT.CPP $$root$$.cpp ROOT.H $$root$$.h +ROOT.RC $$root$$.rc +DOC.CPP $$root$$Doc.cpp DOC.H $$root$$Doc.h +VIEW.CPP $$root$$View.cpp VIEW.H $$root$$View.h =ROOT.ICO res\$$root$$.ico ROOT.RC2 res\$$root$$.rc2 =DOC.ICO res\$$root$$Doc.ico =TOOLBAR.BMP res\Toolbar.bmp |
Figure 10 Template Resource Prefix Characters
Prefix Character |
Meaning |
= |
The template resource contains binary data. If you don't supply this option, the resource must contain text data. |
+ |
The file becomes part of the project. |
* |
Even though you have a template resource in your wizard's resources, you want AppWizard to use the default resource by the same name from Microsoft's DLL. (You might use this feature in a "semi-custom" wizard. With * and some conditional logic, you can sometimes use your own version of a standard template and sometimes use the standard version.) |
Figure 16 ROOT.CLW Template Resource
; CLW file contains information for the MFC ClassWizard
[General Info]
Version=1
LastClass=CAboutBox
LastTemplate=CDialog
NewFileInclude1=#include "stdafx.h"
NewFileInclude2=#include "$$root$$.h"
LastPage=0
ResourceCount=2
Resource1=IDD_ABOUT
Resource2=IDR_MAINMENU
ClassCount=$$numclasses$$ // 3 + # window panes
Class1=CMainWindow
Class2=CAboutBox
Class3=C$$Safe_root$$App
$$paneclass$$
[CLS:CMainWindow]
Type=0
BaseClass=CFrameWnd
HeaderFile=mainwnd.h
ImplementationFile=mainwnd.cpp
LastObject=CMainWindow
Filter=T
VirtualFilter=fWC
[DLG:IDD_ABOUT]
Type=1
Class=CAboutBox
ControlCount=2
Control1=IDOK,button,1342242817
Control2=IDC_STATIC,static,1342308353
[CLS:CAboutBox]
Type=0
HeaderFile=$$root$$.h
ImplementationFile=$$root$$.cpp
BaseClass=CDialog
Filter=D
LastObject=CAboutBox
[CLS:C$$Safe_root$$App]
Type=0
HeaderFile=$$root$$.h
ImplementationFile=$$root$$.cpp
BaseClass=CWinApp
LastObject=C$$Safe_root$$App
Filter=N
VirtualFilter=AC
[MNU:IDR_MAINMENU]
Type=1
Class=?
Command1=ID_APP_EXIT
Command2=ID_APP_ABOUT
CommandCount=2
$$/////////////////////////////////////////////////////////
$$IF(toolbar)
[TB:IDR_MAINMENU]
Type=1
Class=?
Command1=ID_FILE_NEW
Command2=ID_FILE_OPEN
Command3=ID_FILE_SAVE
Command4=ID_EDIT_CUT
Command5=ID_EDIT_COPY
Command6=ID_EDIT_PASTE
Command7=ID_FILE_PRINT
Command8=ID_APP_ABOUT
CommandCount=8
$$ENDIF // toolbar
$$/////////////////////////////////////////////////////////
$$IF(treepane)
[CLS:CTreePane]
Type=0
HeaderFile=treepane.h
ImplementationFile=treepane.cpp
BaseClass=CWnd
Filter=W
LastObject=CTreePane
VirtualFilter=WC
$$ENDIF // treepane
$$/////////////////////////////////////////////////////////
$$IF(datapane)
[CLS:CDataPane]
Type=0
HeaderFile=datapane.h
ImplementationFile=datapane.cpp
BaseClass=CWnd
Filter=W
LastObject=CDataPane
VirtualFilter=WC
$$ENDIF // datapane
$$/////////////////////////////////////////////////////////
$$IF(stdpane)
[CLS:CStdPane]
Type=0
HeaderFile=stdpane.h
ImplementationFile=stdpane.cpp
BaseClass=CWnd
LastObject=CStdPane
$$ENDIF // stdpane
Figure 17 OnDismiss
BOOL CCustom1Dlg::OnDismiss()
{ // CCustom1Dlg::OnDismiss
if (!UpdateData(TRUE))
return FALSE;
#define d Undocaw.m_Dictionary
#define ds(n,v) d[_T(#n)] = _T(#v)
#define dr(n) d.RemoveKey(_T(#n))
int numclasses = 0;
CString paneclass;
if (m_treepane)
{ // tree pane included
ds(treepane, 1);
paneclass += csprintf("Class%d=CTreePane\n", numclasses+4);
++numclasses;
} // tree pane included
else
dr(treepane);
if (m_datapane)
{ // tree pane included
ds(datapane, 1);
paneclass += csprintf("Class%d=CDataPane\n", numclasses+4);
++numclasses;
} // tree pane included
else
dr(datapane);
if (m_stdpane)
{ // tree pane included
ds(stdpane, 1);
paneclass += csprintf("Class%d=CStdPane\n", numclasses+4);
++numclasses;
} // tree pane included
else
dr(stdpane);
d[_T("numclasses")] = csprintf("%d", numclasses+3);
d[_T("numpanes")] = csprintf("%d", numclasses);
d[_T("paneclass")] = paneclass;
if (numclasses > 1)
ds(multipane, 1);
else
dr(multipane);
if (m_toolbar)
{ // toolbar requested
ds(toolbar, 1);
if (m_dockable)
ds(dockable, 1);
else
dr(dockable);
if (m_tooltips)
ds(tooltips, 1);
else
dr(tooltips);
} // toolbar requested
else
{ // no toolbar requested
dr(toolbar);
dr(dockable);
dr(tooltips);
} // no toolbar requested
if (m_statusbar)
{ // status bar requested
ds(statusbar, 1);
if (m_indicators)
ds(indicators, 1);
else
dr(indicators);
} // status bar requested
else
{ // no status bar requested
dr(statusbar);
dr(indicators);
} // no status bar requested
return TRUE; // i.e., okay to dismiss dialog
} // CCustom1Dlg::OnDismiss
Figure A CTippyDialog Member Functions
BOOL CTippyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
theApp.m_dialog = this;
theApp.m_tip = &m_tip;
m_tip.Create(this);
EnumChildWindows(m_hWnd, EnumChildProc, (LPARAM) this);
m_tip.Activate(TRUE);
return TRUE;
}
BOOL CALLBACK CTippyDialog::EnumChildProc(HWND hwnd, LPARAM lParam)
{
CTippyDialog* me = (CTippyDialog*) lParam;
char classname[64];
GetClassName(hwnd, classname, sizeof(classname));
if (stricmp(classname, "STATIC") == 0)
return TRUE;
UINT id = GetWindowLong(hwnd, GWL_ID);
TOOLINFO ti;
memset(&ti, 0, sizeof(ti));
ti.cbSize = sizeof(ti);
ti.hwnd = me->m_hWnd;
ti.uFlags = TTF_IDISHWND;
ti.uId = (UINT) hwnd;
ti.hinst = AfxGetResourceHandle();
ti.lpszText = MAKEINTRESOURCE(id);
me->m_tip.SendMessage(TTM_ADDTOOL, 0, (LPARAM) &ti);
return TRUE;
}
void CTippyDialog::PostNcDestroy()
{
CDialog::PostNcDestroy();
theApp.m_dialog = NULL;
theApp.m_tip = NULL;
}