Kỹ thuật chung của việc cho phép một trường hợp cửa sổ để được đại diện bởi dụ như lớp là để tận dụng SetWindowLongPtr và GetWindowLongPtr để liên kết con trỏ cá thể lớp của bạn với cửa sổ xử lý. Dưới đây là một số mã mẫu để giúp bạn bắt đầu. Nó có thể không biên dịch mà không có một vài chỉnh sửa. Nó chỉ có nghĩa là một tham chiếu.
Cá nhân, tôi đã ngừng phân lớp lớp cửa sổ của riêng mình cách đây vài năm khi tôi phát hiện ra lớp mẫu CWindow và CWindowImpl của ATL. Họ quan tâm đến việc thực hiện tất cả các mã hóa trần tục này cho bạn để có thể tập trung vào việc viết các phương thức xử lý các thông điệp cửa sổ. Xem mã ví dụ tôi đã viết here.
Hy vọng điều này sẽ hữu ích.
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);
};
};
Xem [ Phương pháp tốt nhất để lưu trữ con trỏ này để sử dụng trong WndProc ] (http://stackoverflow.com/questions/117792/best-method-for-storing-this-pointer-for-use-in-wndproc). –
Đó là vì lý do này mà tôi luôn mong rằng 'WndProc' có tham số' void * user_data'. Nó sẽ làm cho việc tạo ra một wrapper dựa trên đối tượng dễ dàng hơn nhiều. –
@Evan: vâng, nhưng nó cũng đã yêu cầu ai đó * sane * chịu trách nhiệm thiết kế API ... API Win32 sẽ là một con thú rất khác nếu đó là trường hợp. – jalf