Die allgemeine Technik ein Fenster Instanz ermöglicht, indem sie als Klasseninstanz dargestellt werden soll, Gebrauch machen SetWindowLongPtr und GetWindowLongPtr, um den Klasseninstanzzeiger mit dem Fensterhandle zu verknüpfen. Unten finden Sie einen Beispielcode, mit dem Sie beginnen können. Es kann nicht ohne ein paar Optimierungen kompilieren. Es soll nur eine Referenz sein.
Ich persönlich habe vor ein paar Jahren aufgehört, meine eigenen Fensterklassen zu erstellen, als ich ATLs CWindow- und CWindowImpl-Vorlagenklasse entdeckte. Sie kümmern sich darum, all diese alltägliche Kodierung für Sie zu tun, und können sich darauf konzentrieren, nur Methoden zu schreiben, die Fenstermeldungen verarbeiten. Siehe den Beispielcode, den ich geschrieben habe here.
Hoffe, das hilft.
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);
};
};
See [ Beste Methode für diesen Zeiger für die Verwendung in WndProc Speicherung ] (http://stackoverflow.com/questions/117792/best-method-for-storing-this-pointer-for-use-in-wndproc). –
Aus diesem Grund habe ich mir immer gewünscht, dass 'WndProc' einen' void * user_data' Parameter hat. Es würde das Erstellen eines objektbasierten Wrappers einfach einfacher machen. –
@Evan: yep, aber es hätte auch jemand * sane * benötigt, um die API zu entwerfen ... Die Win32 API wäre ein ganz anderes Biest gewesen, wenn das der Fall gewesen wäre. – jalf