class CWinApp : public CWinThread
{
DECLARE_DYNAMIC(CWinApp)
public:
// Constructor
CWinApp(LPCTSTR lpszAppName = NULL); // app name defaults to EXE name
// Attributes
// Startup args (do not change)
HINSTANCE m_hInstance;
HINSTANCE m_hPrevInstance;
LPTSTR m_lpCmdLine;
int m_nCmdShow;
// Running args (can be changed in InitInstance)
LPCTSTR m_pszAppName; // human readable name
// (from constructor or AFX_IDS_APP_TITLE)
LPCTSTR m_pszRegistryKey; // used for registry entries
CDocManager* m_pDocManager;
// Support for Shift+F1 help mode.
BOOL m_bHelpMode; // are we in Shift+F1 mode?
public: // set in constructor to override default
LPCTSTR m_pszExeName; // executable name (no spaces)
LPCTSTR m_pszHelpFilePath; // default based on module path
LPCTSTR m_pszProfileName; // default based on app name
// Initialization Operations - should be done in InitInstance
protected:
void LoadStdProfileSettings(UINT nMaxMRU = _AFX_MRU_COUNT); // load MRU file list and last preview state
void EnableShellOpen();
#ifndef _AFX_NO_GRAYDLG_SUPPORT
void SetDialogBkColor(COLORREF clrCtlBk = RGB(192, 192, 192),
COLORREF clrCtlText = RGB(0, 0, 0));
// set dialog box and message box background color
#endif
void SetRegistryKey(LPCTSTR lpszRegistryKey);
void SetRegistryKey(UINT nIDRegistryKey);
// enables app settings in registry instead of INI files
// (registry key is usually a "company name")
#ifndef _AFX_NO_CTL3D_SUPPORT
BOOL Enable3dControls(); // use CTL3D32.DLL for 3D controls in dialogs
#ifndef _AFXDLL
BOOL Enable3dControlsStatic(); // statically link CTL3D.LIB instead
#endif
#endif
void RegisterShellFileTypes(BOOL bCompat=FALSE);
// call after all doc templates are registered
void RegisterShellFileTypesCompat();
// for backwards compatibility
void UnregisterShellFileTypes();
// Helper Operations - usually done in InitInstance
public:
// Cursors
HCURSOR LoadCursor(LPCTSTR lpszResourceName) const;
HCURSOR LoadCursor(UINT nIDResource) const;
HCURSOR LoadStandardCursor(LPCTSTR lpszCursorName) const; // for IDC_ values
HCURSOR LoadOEMCursor(UINT nIDCursor) const; // for OCR_ values
// Icons
HICON LoadIcon(LPCTSTR lpszResourceName) const;
HICON LoadIcon(UINT nIDResource) const;
HICON LoadStandardIcon(LPCTSTR lpszIconName) const; // for IDI_ values
HICON LoadOEMIcon(UINT nIDIcon) const; // for OIC_ values
// Profile settings (to the app specific .INI file, or registry)
UINT GetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault);
BOOL WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue);
CString GetProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry,
LPCTSTR lpszDefault = NULL);
BOOL WriteProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry,
LPCTSTR lpszValue);
BOOL GetProfileBinary(LPCTSTR lpszSection, LPCTSTR lpszEntry,
LPBYTE* ppData, UINT* pBytes);
BOOL WriteProfileBinary(LPCTSTR lpszSection, LPCTSTR lpszEntry,
LPBYTE pData, UINT nBytes);
BOOL Unregister();
LONG DelRegTree(HKEY hParentKey, const CString& strKeyName);
// Running Operations - to be done on a running application
// Dealing with document templates
void AddDocTemplate(CDocTemplate* pTemplate);
POSITION GetFirstDocTemplatePosition() const;
CDocTemplate* GetNextDocTemplate(POSITION& pos) const;
// Dealing with files
virtual CDocument* OpenDocumentFile(LPCTSTR lpszFileName); // open named file
virtual void AddToRecentFileList(LPCTSTR lpszPathName); // add to MRU
// Printer DC Setup routine, 'struct tagPD' is a PRINTDLG structure
void SelectPrinter(HANDLE hDevNames, HANDLE hDevMode,
BOOL bFreeOld = TRUE);
BOOL CreatePrinterDC(CDC& dc);
#ifndef _UNICODE
BOOL GetPrinterDeviceDefaults(struct tagPDA* pPrintDlg);
#else
BOOL GetPrinterDeviceDefaults(struct tagPDW* pPrintDlg);
#endif
// Command line parsing
BOOL RunEmbedded();
BOOL RunAutomated();
void ParseCommandLine(CCommandLineInfo& rCmdInfo);
BOOL ProcessShellCommand(CCommandLineInfo& rCmdInfo);
// Overridables
// hooks for your initialization code
virtual BOOL InitApplication();
// exiting
virtual BOOL SaveAllModified(); // save before exit
void HideApplication();
void CloseAllDocuments(BOOL bEndSession); // close documents before exiting
// Advanced: to override message boxes and other hooks
virtual int DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt);
virtual void DoWaitCursor(int nCode); // 0 => restore, 1=> begin, -1=> end
// Advanced: process async DDE request
virtual BOOL OnDDECommand(LPTSTR lpszCommand);
// Advanced: Help support
virtual void WinHelp(DWORD dwData, UINT nCmd = HELP_CONTEXT);
// Command Handlers
protected:
// map to the following for file new/open
afx_msg void OnFileNew();
afx_msg void OnFileOpen();
// map to the following to enable print setup
afx_msg void OnFilePrintSetup();
// map to the following to enable help
afx_msg void OnContextHelp(); // shift-F1
afx_msg void OnHelp(); // F1 (uses current context)
afx_msg void OnHelpIndex(); // ID_HELP_INDEX
afx_msg void OnHelpFinder(); // ID_HELP_FINDER, ID_DEFAULT_HELP
afx_msg void OnHelpUsing(); // ID_HELP_USING
// Implementation
protected:
HGLOBAL m_hDevMode; // printer Dev Mode
HGLOBAL m_hDevNames; // printer Device Names
DWORD m_dwPromptContext; // help context override for message box
int m_nWaitCursorCount; // for wait cursor (>0 => waiting)
HCURSOR m_hcurWaitCursorRestore; // old cursor to restore after wait cursor
CRecentFileList* m_pRecentFileList;
void UpdatePrinterSelection(BOOL bForceDefaults);
void SaveStdProfileSettings(); // save options to .INI file
public: // public for implementation access
CCommandLineInfo* m_pCmdInfo;
ATOM m_atomApp, m_atomSystemTopic; // for DDE open
UINT m_nNumPreviewPages; // number of default printed pages
size_t m_nSafetyPoolSize; // ideal size
void (AFXAPI* m_lpfnDaoTerm)();
void DevModeChange(LPTSTR lpDeviceName);
void SetCurrentHandles();
int GetOpenDocumentCount();
// helpers for standard commdlg dialogs
BOOL DoPromptFileName(CString& fileName, UINT nIDSTitle,
DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
int DoPrintDialog(CPrintDialog* pPD);
void EnableModeless(BOOL bEnable); // to disable OLE in-place dialogs
// overrides for implementation
virtual BOOL InitInstance();
virtual int ExitInstance(); // return app exit code
virtual int Run();
virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing
virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg);
public:
virtual ~CWinApp();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// helpers for registration
HKEY GetSectionKey(LPCTSTR lpszSection);
HKEY GetAppRegistryKey();
protected:
//{{AFX_MSG(CWinApp)
afx_msg void OnAppExit();
afx_msg void OnUpdateRecentFileMenu(CCmdUI* pCmdUI);
afx_msg BOOL OnOpenRecentFile(UINT nID);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
1:
public:
// Constructor
CWinApp(LPCTSTR lpszAppName = NULL); // app name defaults to EXE name
为什么不把CWinApp构造函数设置为Protected呢?,这明显和CView的设计不一样?CWinApp必须继承出来,overrided Initinstace()函数才可以使用。
如下:
BOOL CEx03aApp::InitInstance()
{AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CEx03aDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CEx03aView));
AddDocTemplate(pDocTemplate);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo))
return FALSE;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;}
难道,CWinApp还有什么不可告人的秘密?或者纯属MFC小组的疏忽?
2:...
public:
// Attributes
// Startup args (do not change)
HINSTANCE m_hInstance;
HINSTANCE m_hPrevInstance;
LPTSTR m_lpCmdLine;
int m_nCmdShow;
...
看也能看出来是,存放WinMain函数的命令参数,很多朋友可能奇怪,如果在delphi中,如何取得像WinMain的命令参数?因为,delphi的入口不是函数,而是begin...end. Delphi当然可以取命令参数,使用Object Pascal的函数就可以。
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
...
}
这么一看,好像,不符合OO规则,因为类数据怎么能public出去呢?其实世界没有什么东西是“绝对的”,除了“运动”:),,如果不把数据public,必须使用很多的,HINSTANCE GetXXX(){} 和 void SetXXX(HINSTANCE h){},这样的函数,这样的函数,用在这里与C++的效率,灵活的哲学思想是违背的,可以说是C++的丑陋代码,那么什么代码是可以public出去,什么必须private来隐藏呢?假如类数据是可以任何赋值,不需要加以监测,把它public出去就可以了。反之,必须private!那么,什么类的行为可以作为类的成员函数,而那些不需要成为类成员函数呢?按照,C++之父的设计思想:
类 = 数据 + 行为,条件是:在类隐含的不变性下。假如一个类的行为没有维护“隐含的不变性”,则把该函数作为外部函数即可。
假如类隐含的不变性是:F, 类名:C, 数据:A; 类行为:B,,则:F(C) = A + B; 嗯,扯远了。
3:
// Cursors
HCURSOR LoadCursor(LPCTSTR lpszResourceName) const;
HCURSOR LoadCursor(UINT nIDResource) const;
HCURSOR LoadStandardCursor(LPCTSTR lpszCursorName) const; // for IDC_ values
HCURSOR LoadOEMCursor(UINT nIDCursor) const; // for OCR_ values
// Icons
HICON LoadIcon(LPCTSTR lpszResourceName) const;
HICON LoadIcon(UINT nIDResource) const;
HICON LoadStandardIcon(LPCTSTR lpszIconName) const; // for IDI_ values
HICON LoadOEMIcon(UINT nIDIcon) const; // for OIC_ values
...
有是一大堆GUI方法,在Delphi,把这些方法做成了属性,并把这些信息放在了*.frm窗体代码里,并不作为*.pas代码的一部分。pas代码负责的是,逻辑代码。所以同样功能的VC的.h/cpp代码和pas代码,pas代码显得非常简练,干净。如果是VC的话,你还得花一部分精力放在GUI上,ft,,,,
4:
protected:
// map to the following for file new/open
afx_msg void OnFileNew();
afx_msg void OnFileOpen();
// map to the following to enable print setup
afx_msg void OnFilePrintSetup();
// map to the following to enable help
afx_msg void OnContextHelp(); // shift-F1
afx_msg void OnHelp(); // F1 (uses current context)
afx_msg void OnHelpIndex(); // ID_HELP_INDEX
afx_msg void OnHelpFinder(); // ID_HELP_FINDER, ID_DEFAULT_HELP
afx_msg void OnHelpUsing(); // ID_HELP_USING
这一段是事件代码。CWinApp这作用,在Delphi中的TApplication与之一一些关联,但由于框架设计思想不一样,这2个类的目的和实现大相径庭。MFC使用的是MVC框架设计模式,而Delphi使用的是Layer Service框架设计模式
to be continued ---by littleroy 2004-7-2