La técnica general de permitir que una instancia de la ventana a ser representado por ejemplo como clase es hacer uso de SetWindowLongPtr y GetWindowLongPtr para asociar el puntero de instancia de clase con el manejador de ventana. A continuación se muestra un código de muestra para comenzar. Puede no compilar sin algunos ajustes. Solo tiene la intención de ser una referencia.
Personalmente, dejé de rodar mis propias clases de ventana hace unos años cuando descubrí la clase de plantilla CWindow y CWindowImpl de ATL. Ellos se encargan de hacer toda esta codificación mundana para ti, así que puedes concentrarte solo en escribir métodos que manejen mensajes de ventana. Ver el código de ejemplo que escribí here.
Espero que esto ayude.
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);
};
};
Ver [ El mejor método para almacenar este puntero para usar en WndProc ] (http://stackoverflow.com/questions/117792/best-method-for-storing-this-pointer-for-use-in-wndproc) –
Es por esta razón que siempre he deseado que 'WndProc' tuviera un parámetro' void * user_data'. Sería mucho más fácil crear un contenedor basado en objetos. –
@Evan: sí, pero también habría requerido que alguien * cuerdo * se encargue de diseñar la API ... La API de Win32 habría sido una bestia muy diferente si ese hubiera sido el caso. – jalf