• WTL学习(一)窗口框架


    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;
    }

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

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












  • 相关阅读:
    pexpect模块
    Python正则表达式
    telnetlib
    paramiko
    threadpool和Queue
    logging
    Python异常
    Python迭代器
    程序员工资那么高,却从不炫富?网友回复让人“笑喷了”!
    小白到web前端工程师需要学习哪些知识?
  • 原文地址:https://www.cnblogs.com/kwliu/p/2129633.html
Copyright © 2020-2023  润新知