简体   繁体   English

面向对象的 C++ win32?

[英]Object oriented c++ win32?

I want to create my own class to handle creating windows and the window procedure but I have noticed that the window procedure has to be static!我想创建自己的类来处理创建窗口和窗口过程,但我注意到窗口过程必须是静态的! I'm now wondering whether its possible to make the window procedure object oriented?我现在想知道是否可以使窗口过程面向对象? I have read some tutorials on object oriented windows, but they always make the procedure static -.- whats the use in that?我已经阅读了一些关于面向对象窗口的教程,但它们总是使程序静态-.- 那有什么用? :/ :/

Any links or info on how to get around this problem would be appreciated,任何有关如何解决此问题的链接或信息将不胜感激,

thanks谢谢

You can get around that by making the static WndProc delegate everything to the members:您可以通过使静态 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;
}

The general technique of allowing a window instance to be represented by as class instance is to make use of the SetWindowLongPtr and GetWindowLongPtr to associate your class instance pointer with the window handle.允许将窗口实例表示为类实例的一般技术是利用 SetWindowLongPtr 和 GetWindowLongPtr 将类实例指针与窗口句柄相关联。 Below is some sample code to get you started.下面是一些示例代码,可帮助您入门。 It may not compile without a few tweaks.如果没有一些调整,它可能无法编译。 It's only meant to be a reference.它只是作为一个参考。

Personally, I've stopped rolling my own window classes back a few years ago when I discovered ATL's CWindow and CWindowImpl template class.就个人而言,几年前当我发现 ATL 的 CWindow 和 CWindowImpl 模板类时,我已经停止回滚我自己的窗口类。 They take care of doing all this mundane coding for you so can focus on just writing methods that handle window messages.他们负责为您完成所有这些平凡的编码,因此可以专注于编写处理窗口消息的方法。 See the example code I wrote up here .请参阅我在此处编写的示例代码。

Hope this helps.希望这可以帮助。

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

Just to add to Brian's answer but for a win32 framework that's more beginner friendly take a look at Win32++ .只是为了添加到 Brian 的答案,但对于对初学者更友好的 win32 框架,请查看Win32++ The library itself isn't as comprehensive in features compared to MFC or QT but that is a tradeoff the designer made at the beginning to keep the library easy to understand and simple to use.与 MFC 或 QT 相比,库本身的功能并不全面,但这是设计师在开始时做出的权衡,以保持库易于理解和使用。

If you're still interested in this topic, I highly encourage you to take a look at it since it uses yet another technique for saving the 'this' pointer by utilizing thread local storage.如果您仍然对这个主题感兴趣,我强烈建议您查看它,因为它使用另一种技术通过利用线程本地存储来保存“this”指针。

You can use the window handle passed to the WindowProc to grab an object you've created for that particular window and delegate the event handling to that object.您可以使用传递给 WindowProc 的窗口句柄来获取您为该特定窗口创建的对象并将事件处理委托给该对象。

eg例如

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

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

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