我正在尝试使用 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;
}