Объектно-ориентированный C++ win32?

Я хочу создать свой собственный класс для обработки окон создания и оконной процедуры, но я заметил, что оконная процедура должна быть статичной! Я теперь задаюсь вопросом ли ее возможное для создания оконной процедуры объектно-ориентированной? Я прочитал некоторые учебные руководства на объектно-ориентированных окнах, но они всегда делают процедуру, статические-.-что проку в этом?:/

Любые ссылки или информация о том, как обойти эту проблему, ценились бы,

спасибо

8
задан Kaije 1 August 2010 в 00:32
поделиться

4 ответа

Вы можете обойти это, заставив статический 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;
}
11
ответ дан 5 December 2019 в 07:10
поделиться

Если вам нужен объектно-ориентированный Win32 API, вам следует обратиться к MFC и / или WTL .

3
ответ дан 5 December 2019 в 07:10
поделиться

Вы можете использовать дескриптор окна, переданный WindowProc, чтобы захватить объект, который вы создали для этого конкретного окна, и делегировать обработку событий этому объекту.

например.

IMyWindowInterface* pWnd = getMyWindowObject(hWnd);
pWnd->ProcessMessage(uMsg, wParam, lParam);
1
ответ дан 5 December 2019 в 07:10
поделиться

Общий метод разрешения экземпляра окна быть представлен в виде экземпляра класса: используйте 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);
    };


};
6
ответ дан 5 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: