Ogólna technika pozwala instancji okna mają być reprezentowane przez co klasy instancji jest do wykorzystania SetWindowLongPtr i GetWindowLongPtr do powiązania wskaźnika instancji klasy z uchwytem okna. Poniżej znajduje się przykładowy kod, aby rozpocząć. Może się nie skompilować bez kilku poprawek. To ma być tylko odniesienie.
Osobiście przestałem rozwijać własne klasy okienne kilka lat temu, kiedy odkryłem klasę szablonów ATW CWindow i CWindowImpl. Dbają o to, abyś zrobił to przyziemne kodowanie, więc możesz skupić się na pisaniu metod, które obsługują wiadomości w oknie. Zobacz przykładowy kod, który napisałem: here.
Mam nadzieję, że to pomoże.
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);
};
};
Zobacz najlepszą metodę przechowywania tego wskaźnika do użytku w WndProc ] (http://stackoverflow.com/questions/117792/best-method-for-storing-this-pointer-for-use-in-wndproc). –
Z tego powodu zawsze chciałem, aby 'WndProc' miał parametr" void * user_data ". Dzięki temu tworzenie wrapperów opartych na obiektach byłoby o wiele łatwiejsze. –
@Evan: Tak, ale wymagałoby to również kogoś * przy zdrowych zmysłach * do projektowania interfejsu API ... Win32 API byłby zupełnie inną bestią, gdyby tak było. – jalf