您当前的位置: 首页 >  ui

插件开发

暂无认证

  • 2浏览

    0关注

    492博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

第一章 第四小节Duilib的WindowImplBase基类(二)--CWindowWnd

插件开发 发布时间:2022-03-23 12:40:28 ,浏览量:2

文章目录
    • 1.CWindowWnd类
    • 2.作者答疑

1.CWindowWnd类

  在duilib中,绘制对象的目标载体是窗口,那就必然有窗口部分的内容需要处理,在WindowImplBase中,封装在父类CWindowWnd中,如下所示:

class UILIB_API CWindowWnd
    {
    public:
        CWindowWnd();

        HWND GetHWND() const;
        operator HWND() const;//类型转换函数
        
		//注册窗口类
        bool RegisterWindowClass();
        bool RegisterSuperclass(); // 超类化,hinst—定义窗口类XXXXXX的模块的句柄,如为系统定义的窗口类(如:EDIT、BUTTON)则hinst=NULL.。 

		//创建窗口
        HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, const RECT rc, HMENU hMenu = NULL);
        HWND Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int cx = CW_USEDEFAULT, int cy = CW_USEDEFAULT, HMENU hMenu = NULL);
        HWND CreateDuiWindow(HWND hwndParent, LPCTSTR pstrWindowName,DWORD dwStyle =0, DWORD dwExStyle =0);
		//保存窗口与对象的映射、修改窗口过程函数和解绑
        HWND Subclass(HWND hWnd);
        void Unsubclass();
		
		//显示窗口
        void ShowWindow(bool bShow = true, bool bTakeFocus = true);
        UINT ShowModal();
        void Close(UINT nRet = IDOK);
        void CenterWindow();    // 居中,支持扩展屏幕
        void SetIcon(UINT nRes);// 修改窗口图标
		
		//系统函数的封装
        LRESULT SendMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
        LRESULT PostMessage(UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0L);
        void ResizeClient(int cx = -1, int cy = -1);//修改客户端区域大小

    protected:
        virtual LPCTSTR GetWindowClassName() const = 0;
        virtual LPCTSTR GetSuperClassName() const;
        virtual UINT GetClassStyle() const;

        virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
        virtual void OnFinalMessage(HWND hWnd);

        static LRESULT CALLBACK __WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
        static LRESULT CALLBACK __ControlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

    protected:
        HWND m_hWnd;
        WNDPROC m_OldWndProc;
        bool m_bSubclassed;
    };

  部分内容写在注释里,耐心的读者,请在以上源代码中阅读,可以学习下,在Subclass函数中,如何修改窗口函数、建立窗口和窗口对象指针联系的方法。但这个函数,在duilib中,并没有调用。窗口函数的指定,还是在RegisterWindowClass或者RegisterSuperclass中完成的。   在窗口的创建过程中,提供了两种方法注册窗口程序,一种是独立窗口,另外一种是子控件的方法,对应着两个注册函数 bool RegisterWindowClass(),bool RegisterSuperclass();   其次查看窗口中最重要的窗口消息函数,如下所示:

LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    CWindowWnd* pThis = NULL;
    if( uMsg == WM_NCCREATE ) {//创建窗口消息
        LPCREATESTRUCT lpcs = reinterpret_cast(lParam);//获取创建窗口时的创建参数
        pThis = static_cast(lpcs->lpCreateParams);
        pThis->m_hWnd = hWnd;
        ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast(pThis));
    } 
    else {
        pThis = reinterpret_cast(::GetWindowLongPtr(hWnd, GWLP_USERDATA));//获取保存的窗口对象
        if( uMsg == WM_NCDESTROY && pThis != NULL ) {
            LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam);
            ::SetWindowLongPtr(pThis->m_hWnd, GWLP_USERDATA, 0L);
            if( pThis->m_bSubclassed ) pThis->Unsubclass();
            pThis->m_hWnd = NULL;
            pThis->OnFinalMessage(hWnd);
            return lRes;
        }
    }
    if( pThis != NULL ) {
        return pThis->HandleMessage(uMsg, wParam, lParam);//窗口自定义的消息处理
    } 
    else {
        return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

  从上述函数中可以得出,HandleMessage是窗口的消息处理函数。同时它是一个虚函数,子类可以通过虚函数的特征来修改这个窗口消息函数。

2.作者答疑

  如有疑问,请留言。

关注
打赏
1665481431
查看更多评论
立即登录/注册

微信扫码登录

0.0391s