对MFC指手划脚(3)

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值