繁体   English   中英

面向对象的 C++ win32?

[英]Object oriented c++ win32?

我想创建自己的类来处理创建窗口和窗口过程,但我注意到窗口过程必须是静态的! 我现在想知道是否可以使窗口过程面向对象? 我已经阅读了一些关于面向对象窗口的教程,但它们总是使程序静态-.- 那有什么用? :/

任何有关如何解决此问题的链接或信息将不胜感激,

谢谢

您可以通过使静态 WndProc 将所有内容委托给成员来解决这个问题:

// Forward declarations
class MyWindowClass;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

std::map<HWND, MyWindowClass *> windowMap;

// Your class
class MyWindowClass  {
private:
  HWND m_handle;

  // The member WndProc
  LRESULT MyWndProc(UINT message, WPARAM wParam, LPARAM lParam) { /* ... */ }

public:
  MyWindowClass()
  {
    /* TODO: Create the window here and assign its handle to m_handle */
    /* Pass &WndProc as the pointer to the Window procedure */

    // Register the window
    windowMap[m_handle] = this;
  }
};

// The delegating WndProc
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  std::map<HWND, MyWindowClass *>::iterator it = windowMap.find(hWnd);
  if (it != windowMap.end())
    return it->second->MyWndProc(message, wParam, lParam);
  return 0;
}

允许将窗口实例表示为类实例的一般技术是利用 SetWindowLongPtr 和 GetWindowLongPtr 将类实例指针与窗口句柄相关联。 下面是一些示例代码,可帮助您入门。 如果没有一些调整,它可能无法编译。 它只是作为一个参考。

就个人而言,几年前当我发现 ATL 的 CWindow 和 CWindowImpl 模板类时,我已经停止回滚我自己的窗口类。 他们负责为您完成所有这些平凡的编码,因此可以专注于编写处理窗口消息的方法。 请参阅我在此处编写的示例代码。

希望这可以帮助。

class CYourWindowClass
{
private:
    HWND m_hwnd;

public:
    LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg)
        {
            case WM_CREATE: return OnCreate(wParam, lParam);
            case wM_PAINT: return OnPaint(wParam, lParam);
            case WM_DESTROY:
            {
                SetWindowLongPtr(m_hwnd, GWLP_USERDATA, NULL);
                m_hwnd = NULL;
                return 0;
            }
        }
        return DefWindowProc(m_hwnd, uMsg, wParam, lParam);

    }

    CYourWindowClass()
    {
        m_hwnd = NULL;
    }

    ~CYourWindowClass()
    {
        ASSERT(m_hwnd == NULL && "You forgot to destroy your window!");
        if (m_hwnd)
        {
            SetWindowLong(m_hwnd, GWLP_USERDATA, 0);
        }
    }

    bool Create(...) // add whatever parameters you want
    {
        HWND hwnd = CreateWindow("Your Window Class Name", "Your Window title", dwStyle, x, y, width, height, NULL, hMenu, g_hInstance, (LPARAM)this);
        if (hwnd == NULL)
            return false;

        ASSERT(m_hwnd == hwnd);
        return true;
    }


    static LRESULT __stdcall StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        CYourWindowClass* pWindow = (CYourWindowClass*)GetWindowLongPtr(hwnd, GWLP_USERDATA);

        if (uMsg == WM_CREATE)
        {
            pWindow = ((CREATESTRUCT*)lParam)->lpCreateParams;
            SetWindowLongPtr(hwnd, GWLP_USERDATA, (void*)pWindow);
            m_hWnd = hwnd;
        }

        if (pWindow != NULL)
        {
            return pWindow->WndProc(uMsg, wParam, lParam);
        }

        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    };


};

如果您正在寻找面向对象的 Win32 API,那么您应该寻找MFC和/或WTL

只是为了添加到 Brian 的答案,但对于对初学者更友好的 win32 框架,请查看Win32++ 与 MFC 或 QT 相比,库本身的功能并不全面,但这是设计师在开始时做出的权衡,以保持库易于理解和使用。

如果您仍然对这个主题感兴趣,我强烈建议您查看它,因为它使用另一种技术通过利用线程本地存储来保存“this”指针。

您可以使用传递给 WindowProc 的窗口句柄来获取您为该特定窗口创建的对象并将事件处理委托给该对象。

例如

IMyWindowInterface* pWnd = getMyWindowObject(hWnd);
pWnd->ProcessMessage(uMsg, wParam, lParam);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM