Общий способ разрешения представления окна в качестве экземпляра класса состоит в том, чтобы использовать SetWindowLongPtr и GetWindowLongPtr, чтобы связать указатель экземпляра класса с дескриптором окна. Ниже приведен пример кода, с которого можно начать. Может не скомпилироваться без нескольких настроек. Это только для справки.
Лично я прекратил откатывать свои собственные классы окон несколько лет назад, когда обнаружил шаблонные классы ATW 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);
};
};