什么是在C ++中的对象中包装HWND的有效方法? [英] What is an efficient way to wrap HWNDs in objects in C++?
问题描述
我一直在使用C ++和Win32(非MFC / ATL),我正在编写自己的类库来包装某些Win32对象(特别是HWND)。
I have been working with C++ and Win32 (non MFC/ATL) I am playing around with writing my own class library to wrap certain Win32 objects (HWNDs in particular).
当涉及到创建窗口时,我发现RegisterClassEx / CreateWindowEx方法非常尴尬。这个设计使得编写简单的类封装很困难(一个必须求助thunk,或TLS或一些其他复杂的机制)。
When it comes to creating windows, I find the "RegisterClassEx / CreateWindowEx" method very awkward. This design makes it hard to write simple class wrappers (one must resort to thunks, or TLS or some other complicated mechanism).
它似乎更简单只是让应用程序在创建窗口时指定窗口过程和用户数据指针。
It seems to me it would have been simpler to just let the application specify the window procedure and a user-data pointer at window creation time.
有没有什么明显的原因我缺少设计选择?
Is there any obvious reason I'm missing for the design choice here? Is there a really simple and efficient way for this to work?
推荐答案
ATL的CWindow和CWindowImpl是你的朋友。
ATL's CWindow and CWindowImpl are your friends.
CWindowImpl负责处理你所说的RegisterClass / CreateWindow尴尬。
CWindowImpl makes takes care of the RegisterClass/CreateWindow awkwardness that you speak of.
CWindow是一个基本的包装器类一个带有所有win32函数的HWND抽象出来。
CWindow is a basic "wrapper" class for an HWND with all the win32 functions abstracted out.
我更喜欢ATL比MFC更好的原因。 ATL是一个非常轻量级的类,提供了所有的源代码。这是一个简单的#include没有额外的库或运行时处理。滚动我自己的WndProcs和窗口封装类多年以后,我发现CWindowImpl一个快乐工作。你必须在你的代码中声明一个全局的AtlModuleExe实例来使用它,但除此之外,ATL还是不行。
The reason I prefer ATL over MFC. ATL is a very lightweight set of classes with all the source code provided. It's a simple #include with no extra libraries or runtimes to deal with. After rolling my own WndProcs and window encapsulation classes for many years, I've found CWindowImpl a joy to work with. You have to declare a global AtlModuleExe instance in your code to use it, but besides that, ATL stays out of the way.
下面这些类的文档链接:
CWindow:
http://msdn.microsoft.com/ en-us / library / d19y607d.aspx
Links to documenation for these classes below: CWindow: http://msdn.microsoft.com/en-us/library/d19y607d.aspx
CWindowImpl:
http://msdn.microsoft.com/en-us/library/h4616bh2.aspx
CWindowImpl: http://msdn.microsoft.com/en-us/library/h4616bh2.aspx
更新:以下是我为您提供的示例代码:
Update: Here's some sample code I dug up for you:
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 ++中的对象中包装HWND的有效方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!