什么是在C ++中的对象中包装HWND的有效方法? [英] What is an efficient way to wrap HWNDs in objects in C++?

查看:105
本文介绍了什么是在C ++中的对象中包装HWND的有效方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆