Direct2D教程窗口未显示

时间:2013-02-04 17:04:54

标签: c++ windows direct2d

我正在尝试使用MSDN的Direct2D基础教程,但窗口不会显示,它输出正常的调试信息,但没有窗口。我试过玩WinMain()参数和ShowWindow()函数,但它仍然拒绝工作。另外在调试信息中有这个,但我不认为这是相关的。 \ NVIDIA Corporation \ coprocmanager \ nvdxgiwrap.dll'。无法找到或打开PDB文件。

这是代码。

#include "RenderHeader.h"

//Main window function.
int WINAPI WinMain(
HINSTANCE /* hInstance */,
HINSTANCE /* hPrevInstance */,
LPSTR /* lpCmdLine */,
int /* nCmdShow */)
{
    // Use HeapSetInformation to specify that the process should
    // terminate if the heap manager detects an error in any heap used
    // by the process.
    // The return value is ignored, because we want to continue running in the
    // unlikely event that HeapSetInformation fails.

    HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);

    if (SUCCEEDED(CoInitialize(NULL)))
    {
        {
        GameRender app;

        if (SUCCEEDED(app.Initialize()))
        {
            //Runs the application message loop.
        app.RunMessageLoop();
        }
        }
        CoUninitialize();
    }
    return 0;
}

GameRender::GameRender() :
    m_hwnd(NULL),
    m_pDirect2DFactory(NULL),
    m_pRenderTarget(NULL),
    m_pLightSlateGrayBrush(NULL),
    m_pCornflowerBlueBrush(NULL)
{
}

GameRender::~GameRender()
{
    SafeRelease(&m_pDirect2DFactory);
    SafeRelease(&m_pRenderTarget);
    SafeRelease(&m_pLightSlateGrayBrush);
    SafeRelease(&m_pCornflowerBlueBrush);
}



HRESULT GameRender::Initialize()
{
    HRESULT hRes;

    /* Initialize device-indpendent resources, such
     as the Direct2D factory.*/
    hRes = CreateDeviceIndependantResources();

    if (SUCCEEDED(hRes))
    {
        WNDCLASSEX Window = { sizeof(WNDCLASSEX) } ;
        Window.style = CS_HREDRAW | CS_VREDRAW;
        Window.lpfnWndProc = GameRender::WndProc;
        Window.cbClsExtra = 0;
        Window.cbWndExtra = sizeof(LONG_PTR);
        Window.hInstance = HINST_THISCOMPONENT;
        Window.hbrBackground = NULL;
        Window.lpszMenuName = NULL;
        Window.hCursor = LoadCursor(NULL, IDI_APPLICATION);
        Window.lpszClassName = L"D2DDemoApp";

        RegisterClassEx(&Window);

        /* Because the CreateWindow function takes its size in pixels,
         obtain the system DPI and use it to scale the window size.*/
        FLOAT DpiX, DpiY;

        /* The factory returns the current system DPI. This is also the value it will use
         to create its own windows.*/
        m_pDirect2DFactory->GetDesktopDpi(&DpiX, &DpiY);

        //Create Window
        m_hwnd = CreateWindow(L"D2PDemoApp", 
            L"Direct 2D Demo App", 
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 
            CW_USEDEFAULT,
            static_cast<UINT>(ceil(640.f * DpiX / 96.f)),
            static_cast<UINT>(ceil(480.f * DpiY / 96.f)),
            NULL, 
            NULL,
            HINST_THISCOMPONENT, 
            this);

        hRes = m_hwnd ? S_OK : E_FAIL;
        if (SUCCEEDED(hRes))
        {
        ShowWindow(m_hwnd, SW_SHOWNORMAL);
        UpdateWindow(m_hwnd);
        }
    }
    return hRes;
}



HRESULT GameRender::CreateDeviceIndependantResources()
{
HRESULT hr = S_OK;

    //Create a direct2D Factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2DFactory);
return hr;
}

HRESULT GameRender::CreateDeviceDependantResources()
{
    HRESULT hr = S_OK;
    if(!&m_pRenderTarget)
    {
RECT rc;
GetClientRect(m_hwnd, &rc);

D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);

//Create a render target.
hr = m_pDirect2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(m_hwnd, size), &m_pRenderTarget);
    if (SUCCEEDED(hr))
        {
            // Create a gray brush.
            hr = m_pRenderTarget->CreateSolidColorBrush(
                D2D1::ColorF(D2D1::ColorF::LightSlateGray),
                &m_pLightSlateGrayBrush);
        }
    if (SUCCEEDED(hr))
        {
            // Create a blue brush.
            hr = m_pRenderTarget->CreateSolidColorBrush(
                D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
                &m_pCornflowerBlueBrush
                );
        }
    }
    return hr;
}

void GameRender::DiscardDeviceResources()
{
    SafeRelease(&m_pRenderTarget);
    SafeRelease(&m_pLightSlateGrayBrush);
    SafeRelease(&m_pCornflowerBlueBrush);
}
void GameRender::RunMessageLoop()
{
    MSG Message;
    while (GetMessage(&Message, NULL, 0, 0))
    {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
}
HRESULT GameRender::OnDraw()
{
    HRESULT hr = S_OK;

    hr = CreateDeviceDependantResources();

    if (SUCCEEDED(hr))
    {
        m_pRenderTarget->BeginDraw();

        m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());

        m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));

        D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();

        // Draw a grid background.
        int width = static_cast<int>(rtSize.width);
        int height = static_cast<int>(rtSize.height);

        for (int x = 0; x < width; x += 10)
        {
            m_pRenderTarget->DrawLine(
                D2D1::Point2F(static_cast<FLOAT>(x), 0.0f),
                D2D1::Point2F(static_cast<FLOAT>(x), rtSize.height),
                m_pLightSlateGrayBrush,
                0.5f
                );
        }

        for (int y = 0; y < height; y += 10)
        {
            m_pRenderTarget->DrawLine(
                D2D1::Point2F(0.0f, static_cast<FLOAT>(y)),
                D2D1::Point2F(rtSize.width, static_cast<FLOAT>(y)),
                m_pLightSlateGrayBrush,
                0.5f
                );
        }

        // Draw two rectangles.
        D2D1_RECT_F rectangle1 = D2D1::RectF(
            rtSize.width/2 - 50.0f,
            rtSize.height/2 - 50.0f,
            rtSize.width/2 + 50.0f,
            rtSize.height/2 + 50.0f
            );

        D2D1_RECT_F rectangle2 = D2D1::RectF(
            rtSize.width/2 - 100.0f,
            rtSize.height/2 - 100.0f,
            rtSize.width/2 + 100.0f,
            rtSize.height/2 + 100.0f
            );


        // Draw a filled rectangle.
        m_pRenderTarget->FillRectangle(&rectangle1, m_pLightSlateGrayBrush);

        // Draw the outline of a rectangle.
        m_pRenderTarget->DrawRectangle(&rectangle2, m_pCornflowerBlueBrush);

        hr = m_pRenderTarget->EndDraw();
    }

    if (hr == D2DERR_RECREATE_TARGET)
    {
        hr = S_OK;
        DiscardDeviceResources();
    }

    return hr;
}

void GameRender::OnResize(UINT width, UINT height)
{
    if (m_pRenderTarget)
    {
        // Note: This method can fail, but it's okay to ignore the
        // error here, because the error will be returned again
        // the next time EndDraw is called.
        m_pRenderTarget->Resize(D2D1::SizeU(width,
        height));
    }
}
LRESULT CALLBACK GameRender::WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
    LRESULT result = 0;

    if (message == WM_CREATE)
    {
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
        GameRender *pGameRender = (GameRender *)pcs->lpCreateParams;

        ::SetWindowLongPtrW(
            hwnd,
            GWLP_USERDATA,
            PtrToUlong(pGameRender)
            );

        result = 1;
    }
    else
    {
        GameRender *pGameRender = reinterpret_cast<GameRender *>(static_cast<LONG_PTR>(
            ::GetWindowLongPtrW(
                hwnd,
                GWLP_USERDATA
                )));

        bool wasHandled = false;

        if (pGameRender)
        {
            switch (message)
            {
            case WM_SIZE:
                {
                    UINT width = LOWORD(lParam);
                    UINT height = HIWORD(lParam);
                    pGameRender->OnResize(width, height);
                }
                result = 0;
                wasHandled = true;
                break;

            case WM_DISPLAYCHANGE:
                {
                    InvalidateRect(hwnd, NULL, FALSE);
                }
                result = 0;
                wasHandled = true;
                break;

            case WM_PAINT:
                {
                    pGameRender->OnDraw();
                    ValidateRect(hwnd, NULL);
                }
                result = 0;
                wasHandled = true;
                break;

            case WM_DESTROY:
                {
                    PostQuitMessage(0);
                }
                result = 1;
                wasHandled = true;
                break;
            }
        }

        if (!wasHandled)
        {
            result = DefWindowProc(hwnd, message, wParam, lParam);
        }
    }

    return result;
}

1 个答案:

答案 0 :(得分:0)

假设你的项目目录中存在“RenderHeader.h”并且它包含windows标题,那么你的问题是你没有向WinMain传递它需要运行的变量。 'HINSTANCE','LPSTR'和'int'都是变量类型,但是你需要给它们一个名字,否则它们不存在而且函数不起作用。 所以这是对的

int WINAPI WinMain( HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR     lpCmdLine,
                    int       uCmdShow )
{
    // The rest of the code
}

在您的问题中的代码中注释了变量的名称:P