【问题标题】:Direct2D window doesn't fully renderDirect2D 窗口未完全呈现
【发布时间】:2014-02-09 00:38:23
【问题描述】:

我才刚刚开始尝试学习 Direct2D 和 Windows,并且一直在学习他们在 MSDN 上的教程。我写的大部分代码都是从他们的网站上手动复制的。我在一个介绍用户输入的教程模块上,代码与上一个模块基本相同,但是程序启动并且窗口永远不会完全呈现;它只是一个白色区域,包括非客户区域应该呈现的位置(顶部栏、侧面和底部)。下面是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;
}
}

如果可以的话,请帮忙!我已经研究了大约一个半小时,找不到任何不一致之处。

头文件中包含一个 BaseWindow 模板类,此代码用于创建和注册窗口类以及所有这些,但头文件是从另一个可以正常工作的程序直接复制的,所以我不认为它需要被包括在内。

【问题讨论】:

    标签: c++ windows direct2d


    【解决方案1】:

    我自己想出来的。原来我忘了在 HandleMessage 方法结束时返回默认的 windows 过程。

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 1970-01-01
      • 2011-02-06
      • 2017-12-25
      • 2021-10-01
      相关资源
      最近更新 更多