zoukankan      html  css  js  c++  java
  • 关于CreateWindowEx及自己封装Window类

    今天看msdn的时候发现之前自己封装的Window类写的完全是错误的。封装window类的时候要建立自己的消息处理函数,但是如果是类成员函数的话,一定要是静态类成员函数才行。所以之前我都把消息处理函数里需要调用的函数都写成静态成员函数...

    先来看看CreateWindowEx函数:

    HWND WINAPI CreateWindowEx(
      _In_      DWORD dwExStyle,
      _In_opt_  LPCTSTR lpClassName,
      _In_opt_  LPCTSTR lpWindowName,
      _In_      DWORD dwStyle,
      _In_      int x,
      _In_      int y,
      _In_      int nWidth,
      _In_      int nHeight,
      _In_opt_  HWND hWndParent,
      _In_opt_  HMENU hMenu,
      _In_opt_  HINSTANCE hInstance,
      _In_opt_  LPVOID lpParam
    );

    最后一个参数LPVOID lpParam用来传递参数。并可以在响应WM_NCCREATE消息的时候,通过lParam参数获取该参数,代码如下:

            if (uMsg == WM_NCCREATE)
            {
                CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
                T* pThis = (T*)pCreate->lpCreateParams;
                SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
           pThis->mhwnd = hwnd;  }

    其中SetWindowLongPtr函数用来保存该参数,并可通过GetWindowLongPtr函数再次获取该参数:

    T* pThis = (T*)GetWindowLongPtr(hwnd, GWLP_USERDATA);

    有了这些,就可以不用把处理消息的函数写成静态函数了,方法如下(摘抄自MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/ff381400(v=vs.85).aspx )

    template <class DERIVED_TYPE> 
    class BaseWindow
    {
    public:
        static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        {
            DERIVED_TYPE *pThis = NULL;
    
            if (uMsg == WM_NCCREATE)
            {
                CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
                pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
                SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
    
                pThis->m_hwnd = hwnd;
            }
            else
            {
                pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
            }
            if (pThis)
            {
                return pThis->HandleMessage(uMsg, wParam, lParam);
            }
            else
            {
                return DefWindowProc(hwnd, uMsg, wParam, lParam);
            }
        }
    
        BaseWindow() : m_hwnd(NULL) { }
    
        BOOL Create(
            PCWSTR lpWindowName,
            DWORD dwStyle,
            DWORD dwExStyle = 0,
            int x = CW_USEDEFAULT,
            int y = CW_USEDEFAULT,
            int nWidth = CW_USEDEFAULT,
            int nHeight = CW_USEDEFAULT,
            HWND hWndParent = 0,
            HMENU hMenu = 0
            )
        {
            WNDCLASS wc = {0};
    
            wc.lpfnWndProc   = DERIVED_TYPE::WindowProc;
            wc.hInstance     = GetModuleHandle(NULL);
            wc.lpszClassName = ClassName();
    
            RegisterClass(&wc);
    
            m_hwnd = CreateWindowEx(
                dwExStyle, ClassName(), lpWindowName, dwStyle, x, y,
                nWidth, nHeight, hWndParent, hMenu, GetModuleHandle(NULL), this
                );
    
            return (m_hwnd ? TRUE : FALSE);
        }
    
        HWND Window() const { return m_hwnd; }
    
    protected:
    
        virtual PCWSTR  ClassName() const = 0;
        virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;
    
        HWND m_hwnd;
    };
    View Code

    具体就是窗口创建时传递this指针。处理消息时调用

    this->HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) 方法
  • 相关阅读:
    idea 将java导出为可执行jar及导入jar依赖
    使用idea 调试java -jar xxx.jar方式启动
    springboot 打成的jar包在ClassLoader().getResource方法读取文件为null
    maven 使用dependencyManagement统一管理依赖版本
    Win10系列:C#应用控件基础5
    Win10系列:C#应用控件基础4
    Win10系列:C#应用控件基础3
    Win10系列:C#应用控件基础2
    Win10系列:C#应用控件基础1
    Win10系列:UWP界面布局进阶9
  • 原文地址:https://www.cnblogs.com/zihuyishi/p/3530477.html
Copyright © 2011-2022 走看看