我一直在使用 C++ 和 Win32(非 MFC/ATL)我正在编写自己的类库来包装某些 Win32 对象(特别是 HWND)。
说到创建窗口,我觉得“RegisterClassEx/CreateWindowEx”方法很别扭。这种设计使得编写简单的类包装器变得困难(必须求助于 thunk、TLS 或其他一些复杂的机制)。
在我看来,让应用程序在创建窗口时指定窗口过程和用户数据指针会更简单。
我在这里的设计选择是否有任何明显的原因?有没有一种真正简单有效的方法来实现这一点?
最佳答案
ATL 的 CWindow 和 CWindowImpl 是您的 friend 。
CWindowImpl 使得处理你所说的 RegisterClass/CreateWindow 尴尬。
CWindow 是 HWND 的基本“包装器”类,其中抽象出所有 win32 函数。
我更喜欢 ATL 而不是 MFC 的原因。 ATL 是一组非常轻量级的类,提供了所有源代码。这是一个简单的#include,无需处理额外的库或运行时。在滚动我自己的 WndProcs 和窗口封装类多年之后,我发现使用 CWindowImpl 是一种乐趣。您必须在代码中声明一个全局 AtlModuleExe 实例才能使用它,但除此之外,ATL 不会妨碍您。
这些类(class)的文档链接如下:
窗口:
http://msdn.microsoft.com/en-us/library/d19y607d.aspx
CWindowImpl:
http://msdn.microsoft.com/en-us/library/h4616bh2.aspx
更新:这是我为您挖掘的一些示例代码:
class CMyApp : public CAtlExeModuleT<CMyApp>
{
public:
static HRESULT InitializeCom()
{
CoInitialize(NULL);
return S_OK;
}
};
CMyApp g_app;
class CMyWindow : public CWindowImpl<CMyWindow>
{
public:
CMyWindow();
~CMyWindow();
BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_PAINT, OnPaint);
MESSAGE_HANDLER(WM_CLOSE, OnClose);
END_MSG_MAP();
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled);
LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled);
};
LRESULT CMyWindow::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
{
// your WM_PAINT code goes here
}
LRESULT CMyWindow::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
{
PostQuitMessage();
}
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdline, int nCmdShow)
{
// 640x480 window
CMyWindow appwindow;
RECT rect = {0, 0, 640, 480};
RECT rectActual = {0};
appwindow.Create(NULL, rect, L"App Window", WS_OVERLAPPEDWINDOW);
appwindow.ShowWindow(SW_SHOW);
{
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// app shutdown
appwindow.DestroyWindow();
return 0;
}
关于c++ - 在 C++ 中将 HAND 包装在对象中的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3122695/