WTL学习(一)窗口框架

流过昼夜 提交于 2020-02-05 14:54:43

wtl这个开发框架在开发win32程序方面有很多应用 ,现在chrome和金山等都是用的这个库,所以我要好好学习一下,故写此博客,以推动自己学习。

开始

我从都开始建立一个win32的窗口程序,然后一步一步的添加wtl中的模块,以求达到熟悉win32中的各个api和wtl中类的目的。

首先,包含一下atlapp.h这个头文件。这个头文件中包含了CMessageLoop,这个类主要是用来管理win32的消息循环的(具体的以后再仔细分析吧);CAppModule这个类封装了一个程序中的所有的线程消息循环 。

class CAppModule : public ATL::CComModule{public:    DWORD m_dwMainThreadID;    ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap;    ATL::CSimpleArray<HWND>* m_pSettingChangeNotify;。。。。。。。。。。。}

其中,m_dwMainThreadID是程序主线程的线程ID,m_pMsgLoopMap中维护着所有线程,m_pSettingChangeNotify我还不清楚,在看吧。

在项目中添加一个类CmfMainFrame,然后继承自CWindowImpl<CmfMainFrame>, CWindowImplWTL中所有的窗口封装类的一个实现模板里,封装了基本的窗口相关的api调用。如果要从CWindowImpl类继承,我们必须要定义如下两个宏:

    BEGIN_MSG_MAP(CmfMainFrame)

    END_MSG_MAP()

其中BEGIN_MSG_MAP的定义如下,封装了一个ProcessWindowMessage函数,这个函数是CWindowImpl中的一个虚函数,我们通过在子类中实现出这个函数,才能够实例化它。

#define BEGIN_MSG_MAP(theClass) \public: \    BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) \    { \        BOOL bHandled = TRUE; \        (hWnd); \        (uMsg); \        (wParam); \        (lParam); \        (lResult); \        (bHandled); \        switch(dwMsgMapID) \        { \        case 0:

win32中的编程知识可知,我们要创建一个窗口,必选在定义然后注册这个窗口,然后创建显示,开始程序中的消息循环。CwindowImpl中封装了定义和注册窗口,还有创建和显示。我的CmfMainFrame类得代码如下:

class CmfMainFrame:

    public CWindowImpl<CmfMainFrame>

{

public:

    BEGIN_MSG_MAP(CmfMainFrame)

    END_MSG_MAP()

};

 

然后主程序的代码如下:

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT){    CMessageLoop theLoop;    _Module.AddMessageLoop(&theLoop);    CmfMainFrame wndMain;    if(wndMain.Create(NULL, CWindow::rcDefault, L"KO", WS_OVERLAPPEDWINDOW) == NULL)    {        ATLTRACE(_T("Main window creation failed!\n"));        return 0;    }    wndMain.ShowWindow(nCmdShow);    int nRet = theLoop.Run();    _Module.RemoveMessageLoop();    return nRet;}int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow){    HRESULT hRes = ::CoInitialize(NULL);    ATLASSERT(SUCCEEDED(hRes));    AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES | ICC_USEREX_CLASSES);    hRes = _Module.Init(NULL, hInstance);    ATLASSERT(SUCCEEDED(hRes));    AtlAxWinInit();    int nRet = Run(lpstrCmdLine, nCmdShow);    _Module.Term();    ::CoUninitialize();    return nRet;}

此时,运行程序就可以显示一个窗口了。我们要是点击窗口的X关闭按钮后,不能够结束程序,只是窗口消失了。问题在于我们没有处理WM_DESTROY消息。我们在BEGIN_MSG_MAP中添加一个MESSAGE_HANDLER代码如下:

    BEGIN_MSG_MAP(CmfMainFrame)        MESSAGE_HANDLER(WM_DESTROY, onDestroy)    END_MSG_MAP()    LRESULT onDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)    {        PostQuitMessage(0);        return 0;    }

此时我们点击窗口的关闭按钮后,我们就可以退出程序了。

至此一个简单的窗体就显示出来了。












标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!