简体   繁体   English

Direct2D窗口无法完全呈现

[英]Direct2D window doesn't fully render

I've only just started attempting to learn Direct2D and Windows, and have been going through the tutorials they have on MSDN. 我才刚刚开始尝试学习Direct2D和Windows,并且已经遍历了他们在MSDN上的教程。 Most of the code I've written is pretty much hand-copied from their site. 我编写的大多数代码都是从他们的网站上手工复制的。 I'm on a tutorial module that is an introduction to user input, and the code is mostly the same as the previous module, but the program starts and the window never fully renders; 我在一个教程模块中,它是对用户输入的介绍,其代码与先前的模块基本相同,但是该程序启动了,窗口从未完全渲染。 its just a white area including where the nonclient area should have rendered(the top bar, sides and bottom). 它只是一个白色区域,包括非客户区域应渲染的位置(顶部栏,侧面和底部)。 Below is the code of the main.cpp file: 下面是main.cpp文件的代码:

#ifndef UNICODE
#define UNICODE
#endif // !UNICODE

#include <windowsx.h>
#include <Windows.h>
#include <d2d1.h>
#pragma comment (lib, "d2d1")

#include "BaseWindow.h"

template <class T> void SafeRelease(T **ppT)
{
if(*ppT)
{
    (*ppT)->Release();
    *ppT = NULL;
}
}

class DPIScale
{
static float scaleX;
static float scaleY;

public:
static void Intitialize(ID2D1Factory *pFactory)
{
    FLOAT   dpiX, dpiY;
    pFactory->GetDesktopDpi(&dpiX, &dpiY);
    scaleX = dpiX/96.0f;
    scaleY = dpiY/96.0f;
}

template <typename T>
static D2D1_POINT_2F Pixels_To_DIPs(T x, T y)
{
    return D2D1::Point2F(static_cast<float>(x) / scaleX, static_cast<float>(y)     
 / scaleY);
}
};

float DPIScale::scaleX = 1.0F;
float DPIScale::scaleY = 1.0F;

class MainWindow : public BaseWindow<MainWindow>
{
ID2D1Factory            *pFactory;
ID2D1HwndRenderTarget   *pRenderTarget;
ID2D1SolidColorBrush    *pBrush;
D2D1_ELLIPSE            ellipse;
D2D1_POINT_2F           ptMouse;

HRESULT CreateGraphicsResources();
void    DiscardGraphicsResources();
void    Resize();
void    OnPaint();
void    OnLButtonDown(int pixelX, int pixelY, DWORD flags);
void    OnLButtonUp();
void    OnMouseMove(int pixelX, int pixelY, DWORD flags);

public:

MainWindow() : pFactory(NULL), pRenderTarget(NULL), pBrush(NULL),   
ellipse(D2D1::Ellipse(D2D1::Point2F(), 0, 0)), 
    ptMouse(D2D1::Point2F()) {}

PCWSTR ClassName() const { return L"D2D Drawing Program Class"; }
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
};

HRESULT MainWindow::CreateGraphicsResources()
{
HRESULT hr = S_OK;
if( pRenderTarget == NULL )
{
    RECT rc;
    GetClientRect(m_hwnd, &rc);

    D2D_SIZE_U size = D2D1::SizeU(rc.right, rc.bottom);

    hr = pFactory->CreateHwndRenderTarget(
        D2D1::RenderTargetProperties(),
        D2D1::HwndRenderTargetProperties(m_hwnd, size),
        &pRenderTarget
        );

    if(SUCCEEDED(hr))
    {
        const D2D1_COLOR_F color = D2D1::ColorF(0.0f, 0.0f, 0.0f, 1.0f);
        hr = pRenderTarget->CreateSolidColorBrush(color, &pBrush);
    }
}

return hr;
}

void MainWindow::DiscardGraphicsResources()
{
SafeRelease(&pRenderTarget);
SafeRelease(&pBrush);
}

void MainWindow::OnPaint()
{
HRESULT hr = CreateGraphicsResources();
if(SUCCEEDED(hr))
{
    PAINTSTRUCT ps;
    BeginPaint(m_hwnd, &ps);

    pRenderTarget->BeginDraw();

    pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
    pRenderTarget->FillEllipse(ellipse, pBrush);

    hr = pRenderTarget->EndDraw();
    if(FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
    {
        DiscardGraphicsResources();
    }
    EndPaint(m_hwnd, &ps);
}
}

void MainWindow::Resize()
{
    if (pRenderTarget != NULL)
    {
        RECT rc;
        GetClientRect(m_hwnd, &rc);

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

        pRenderTarget->Resize(size);
        InvalidateRect(m_hwnd, NULL, FALSE);
    }
 }

void MainWindow::OnLButtonDown(int pixelX, int pixelY, DWORD flags)
{
SetCapture(m_hwnd);
ellipse.point = ptMouse = DPIScale::Pixels_To_DIPs(pixelX, pixelY);
ellipse.radiusX = ellipse.radiusY = 1.0f;
InvalidateRect(m_hwnd, NULL, FALSE);
}

void MainWindow::OnLButtonUp()
{
ReleaseCapture();
}

void MainWindow::OnMouseMove(int pixelX, int pixelY, DWORD flags)
{
const D2D1_POINT_2F DIPs = DPIScale::Pixels_To_DIPs(pixelX, pixelY);

const float width = (DIPs.x - ptMouse.x) / 2;
const float height = (DIPs.y - ptMouse.y) / 2;
const float x1 = ptMouse.x + width;
const float y1 = ptMouse.y + height;

ellipse = D2D1::Ellipse(D2D1::Point2F(x1, y1), width, height);

InvalidateRect(m_hwnd, NULL, FALSE);
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow)
{
MainWindow win;

if( !win.Create(L"D2D Drawing Program", WS_OVERLAPPEDWINDOW) )
{
    return 0;
}

ShowWindow(win.Window(), nCmdShow);

MSG msg = {};

while(GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

return 0;
}

LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
    case WM_CREATE:
        if(FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,  
                         &pFactory)))
        {
            return -1;
        }

        // DPIScale::Intitialize(pFactory);
        return 0;

    case WM_DESTROY:
        DiscardGraphicsResources();
        SafeRelease(&pFactory);
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
        OnPaint();
        return 0;

    case WM_SIZE:
        Resize();
        return 0;

    case WM_LBUTTONDOWN:
        OnLButtonDown(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 
                           (DWORD)wParam);
        return 0;

    case WM_LBUTTONUP:
        OnLButtonUp();
        return  0;

    case WM_MOUSEMOVE:
        OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam   
                           (DWORD)wParam);
        return 0;
}
}

Please help if you can! 如果可以的话请帮忙! I've been over it for like an hour and a half now and couldn't find any inconsistencies. 我已经经历了大约一个半小时的时间,找不到任何不一致之处。

There is a BaseWindow template class contained in a header file that this code uses to create and register the window class and all of that, but the header file is a direct copy from another program that works fine so I didn't think that it needed to be included. 头文件中包含一个BaseWindow模板类,该代码用于创建和注册窗口类以及所有其他类,但是头文件是另一个程序的直接副本,可以正常工作,因此我认为不需要被包括。

Figured it out myself. 我自己想通了。 Turns out I forgot to return the default windows procedure at the end of the HandleMessage method. 原来我忘了在HandleMessage方法末尾返回默认的Windows过程。

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

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