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) 方法
  • 相关阅读:
    给python脚本传递命令行参数
    python.exe和pythonw.exe的区别(区分.py、.pyw、.pyc文件)
    python包管理器pip
    python从新手到安装指南
    python基础知识
    使用Lua做为MMOARPG游戏逻辑开发脚本的一点体会
    游戏中各音效的音量默认值
    Unity Editor自定义菜单排序(MenuItem Order)
    没有安装vs通过Rider编译Dll
    MyBatis-Plus 代码生成器
  • 原文地址:https://www.cnblogs.com/zihuyishi/p/3530477.html
Copyright © 2011-2022 走看看