简体   繁体   English

Direct2D教程窗口不显示

[英]Direct2D Tutorial Window No-Show

I'm trying to use MSDN's Direct2D basic tutorial, but the window won't show up, it output's the normal debug info, but no window. 我正在尝试使用MSDN的Direct2D基本教程,但是该窗口不会显示,它输出的是正常的调试信息,但是没有窗口。 I've tried playing about with the WinMain() parameters and the ShowWindow() function, but it still refuses to work. 我尝试过使用WinMain()参数和ShowWindow()函数,但是它仍然无法正常工作。 Allso in the debug info there's this, but i don't think it's relevant. 在调试信息中也有这个,但是我不认为这是相关的。 \\NVIDIA Corporation\\coprocmanager\\nvdxgiwrap.dll'. \\ NVIDIA Corporation \\ coprocmanager \\ nvdxgiwrap.dll”。 Cannot find or open the PDB file. 找不到或打开PDB文件。

Here's the code. 这是代码。

#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;
}

Assuming that "RenderHeader.h" exists in your project's directory and it includes the windows header, then your problem is that you're not passing WinMain the variables it needs to function. 假设项目目录中存在“ RenderHeader.h”,并且其中包含Windows标头,那么您的问题是您没有将所需的变量传递给WinMain。 'HINSTANCE', 'LPSTR' and 'int' are all variable types, but you need to give them a name, otherwise they don't exist and the function won't work. 'HINSTANCE','LPSTR'和'int'都是变量类型,但是您需要给它们命名,否则它们将不存在并且该功能将无法使用。 So this would be right 所以这是正确的

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

The names of the variables are commented out on the code in your question :P 变量名称在问题中的代码中被注释掉:P

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM