如何让WinProc访问由其创建的对象?

时间:2013-03-15 01:35:35

标签: c++ windows winapi

在某些时候,我有这个

LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if(msg==WM_CREATE)
    {
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
            D2DResources* pD2DResources = (D2DResources*)pcs->lpCreateParams;

            ::SetWindowLongPtrW(
                hWnd,
                GWLP_USERDATA,
                PtrToUlong(pD2DResources)
                );
    }
    else
    {
        D2DResources* pD2DResources = reinterpret_cast<D2DResources*>(static_cast<LONG_PTR>(
            ::GetWindowLongPtrW(
                hWnd,
                GWLP_USERDATA
                )));

        switch(msg)
        {

    case WM_PAINT:
        {
            pD2DResources->OnRender();
            ValidateRect(hWnd, NULL);
        }
        break;

    case WM_SIZE:
        {
            UINT width = LOWORD(lParam);
            UINT height = HIWORD(lParam);
            pD2DResources->OnResize(width, height);
        }
        break;

所以我的WinProc可以访问以前创建的D2DResources。现在我希望它可以访问另一个以前创建的对象。我怎么做?我的意思是,它可以访问多个以前创建的对象吗?如果是这样,怎么样?

编辑:Raymond Chen说:&#34;将一个指向结构的指针作为lpCreateParams传递。你可以在结构中放置任何你想要的东西。&#34; 我怎么做?谁能给我一个例子?

1 个答案:

答案 0 :(得分:2)

创建自己的结构并在创建时将其传递给窗口。你可以在那里放任何你喜欢的东西,包括指向其他​​东西的指针。

e.g。

struct MyWindowData
{
    D2DResources*   pD2DResources;
    void*       pMyOtherData;
    int     iSomethingElse;
};


// on window creation
MyWindowData* pData = new MyWindowData(...);
HWND hWnd = CreateWindowEx(..., pData); // window will own the data and destroy it itself

// in the window procedure
if (msg == WM_CREATE)
{
    MyWindowData* pData = ((LPCREATESTRUCT)lParam)->lpCreateParams;
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (ULONG_PTR)pData);
}
else
{
    MyWindowData* pData = (MyWindowData*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    switch (msg)
    {
        case WM_PAINT:
            pData->pD2DResources->OnRender();
            break;

        case WM_NCDESTROY:
            delete pData; // delete data on destroy
            break;
    }

    ...
}