WarmGUI(2) 类CWndApp山寨CWinApp

WarmGUI(2) 类CWndApp山寨CWinApp

自从打算开发一个框架之后,我就没睡好过觉,需要学习思考的东西太多,尤其是水平比较低的时候更加难了。目前虽然开发出来些东西,感觉思路还是有些乱,慢慢都发出来,请教各位高人吧,还是那句话:千里之行始于足下。

MFC中CWinApp类主要做程序的初始化和终止前的清理,并且继承了CWinThread,
class  CWinApp :  public  CWinThread

CWinThread处理与线程相关的一些事务,例如创建线程、挂起和恢复线程、设定线程的优先级,向一个线程发送消息,等等。

而CWinThread又从CCmdTarget继承,
class CWinThread :  public CCmdTarget

CCmdTarget处理OLE,TypeLib这样的一些事务。

但是我并不打算让App类做这样的继承,理由是
1. 作为一个普通的WinApp,可能没有机会处理线程或者OLE的事务,
2. 并不一定需要用继承的关系,用组合的关系或许更好,用@溪流 的话来说,没事不用继承的好,
3. 快速的迭代开发

因此上我把CWndApp的功能暂时局限在初始化和退出应用两个函数上,线程是很重要的,我打算以后实现一个CThread类,而OLE,TypeLib之类的事务,也放在以后来实现,并且可以借鉴@溪流 现在对原生OLE的探索工作。这样看来CWndApp非常简单,但是他和 CWindow类配合应该能够满足最小的应用框架:

 1  class WARMGUI_API CWndApp
 2 {
 3  public:
 4     CWndApp( void);
 5      virtual ~CWndApp( void);
 6 
 7      int UniqueInstance(TCHAR * appname);
 8 
 9      virtual  int InitialApp(HINSTANCE hInstance,  int nCmdShow);
10 
11      virtual  void CleanupApp();
12 
13  protected:
14     HANDLE _hInstanceMutex;
15     HINSTANCE _hInstance;
16 };

其中UniqueInstance函数保证这个应用只运行一个实例,他的实现代码是这样的:
 1  int CWndApp::UniqueInstance(TCHAR * appname)
 2 {
 3      // an instance exists already
 4      _hInstanceMutex = OpenMutex(SYNCHRONIZE, TRUE, appname);
 5      if (_hInstanceMutex)
 6          return (-1);
 7 
 8      // create new instance
 9      _hInstanceMutex = CreateMutex(0, FALSE, appname);
10      if (!_hInstanceMutex)
11          return (-2);
12 
13      return (0);
14 }

InitialApp是一个虚函数,用来初始化应用,例如下面的实现可以保证使用CListView,设置堆信息,初始化COM接口,另外获得一个ID2D1Factory的实例,这是让Direct2D的初始化,在下一次给出这个类的代码。先看InitialApp的示例:
 1  int CWndApp::InitialApp(HINSTANCE hInstance,  int nCmdShow)
 2 {
 3     INITCOMMONCONTROLSEX InitCtrls;
 4     InitCtrls.dwSize =  sizeof(INITCOMMONCONTROLSEX), InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
 5     BOOL b = InitCommonControlsEx(&InitCtrls);
 6 
 7      //  Ignoring the return value because we want to continue running even in the
 8       //  unlikely event that HeapSetInformation fails.
 9      HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
10     CoInitialize(NULL);
11 
12     CDxFactorys::GetInstance()->InitDxFactory();
13      return (0);
14 }

CleanupApp用来做app退出之前的清理工作,针对上面的InitialApp,ClanupApp类似这样释放Direct2D的资源:
1  void CWndApp::CleanupApp()
2 {
3     CDxFactorys::GetInstance()->ReleaseResource();
4     CoUninitialize();
5 }

现在一个简单的应用看起来是这样的:
 1  int APIENTRY _tWinMain(HINSTANCE hInstance,
 2                      HINSTANCE hPrevInstance,
 3                      LPTSTR    lpCmdLine,
 4                       int       nCmdShow)
 5 {
 6     CWndApp app;
 7      if (app.UniqueInstance(L"MyTestWndApp"))
 8          return (0);
 9 
10     app.InitialApp(hInstance, nCmdShow);
11 
12     CMyWindow mainwnd;
13     TCHAR szTitle[MAX_LOADSTRING] = L"MyFirstWindow";
14     TCHAR szClassName[MAX_LOADSTRING] = L"WARMGUIWNDCLASS";
15 
16     BOOL r = mainwnd.InitInstance(hInstance, hPrevInstance, lpCmdLine, nCmdShow, szClassName, szTitle);
17      if (r)
18         mainwnd.RunMessageLoop(0);
19     
20     app.CleanupApp();
21      return (r) ? 0 : -1;
22 }

现在确实很简单,或许应该增加更多的函数,不过貌似一个典型的Win32 App的应用框架已经有点样子了。 现在还有很重要的HDC, Bitmap, Font, Brush等绘图的一大坨东西,不过我并不打算封装他们到类里来,因为这不是WarmGUI的重点,因为即将开始进入DirectX的世界,一个我目前还比较陌生的世界,一边学习一边前进吧 ^_^

你可能感兴趣的:(WarmGUI(2) 类CWndApp山寨CWinApp)