Visual c++ 为什么图形不能在我的窗口中绘制
谁能告诉我为什么我的窗户里什么都没有画。所发生的一切就是它在创建窗口时绘制窗口后面的内容。如果代码太草率,请原谅,我找不到任何东西可以帮助我学习direct2d 1.1,所以有点乱Visual c++ 为什么图形不能在我的窗口中绘制,visual-c++,Visual C++,谁能告诉我为什么我的窗户里什么都没有画。所发生的一切就是它在创建窗口时绘制窗口后面的内容。如果代码太草率,请原谅,我找不到任何东西可以帮助我学习direct2d 1.1,所以有点乱 #include "DemoApp.h" // Provides the application entry point. int WINAPI WinMain( HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, L
#include "DemoApp.h"
// Provides the application entry point.
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)))
{
{
DemoApp app;
if (SUCCEEDED(app.Initialize()))
{
app.RunMessageLoop();
}
}
CoUninitialize();
}
return 0;
}
// DemoApp constructor
DemoApp::DemoApp() :
m_hwnd(NULL),
Direct2DFactory(NULL),
Screen(NULL),
m_pLightSlateGrayBrush(NULL),
m_pCornflowerBlueBrush(NULL),
dxgiDevice(NULL),
dxgiAdapter(NULL),
dxgiFactory(NULL),
Direct3DDevice(NULL),
Direct3dContext(NULL),
Direct2DDevice(NULL),
DXGISwapChain(NULL),
Direct2DBackBuffer(NULL)
{
}
// DemoApp destructor
// Releases the application's resources.
DemoApp::~DemoApp()
{
SafeRelease(&Direct2DFactory);
SafeRelease(&Screen);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
HRESULT DemoApp::LoadBitmapFromFile(ID2D1DeviceContext *pRenderTarget,
IWICImagingFactory2 *pIWICFactory,
PCWSTR uri,
UINT destinationWidth,
UINT destinationHeight,
ID2D1Bitmap1 **ppBitmap
)
{
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pSource = NULL;
IWICStream *pStream = NULL;
IWICFormatConverter *pConverter = NULL;
IWICBitmapScaler *pScalar = NULL;
HRESULT hr = pIWICFactory->CreateDecoderFromFilename(
uri,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
hr = pIWICFactory->CreateFormatConverter(&pConverter);
}
if(SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.0f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
hr = pRenderTarget->CreateBitmapFromWicBitmap(
pConverter,
NULL,
ppBitmap
);
}
SafeRelease(&pDecoder);
SafeRelease(&pSource);
SafeRelease(&pStream);
SafeRelease(&pConverter);
SafeRelease(&pScalar);
return hr;
}
void DemoApp::OpenFilePicker()
{
}
// Creates the application window and device-independent
// resources.
HRESULT DemoApp::Initialize()
{
HRESULT hr;
// Initialize device-indpendent resources, such
// as the Direct2D factory.
hr = CreateDeviceIndependentResources();
if (SUCCEEDED(hr))
{
// Register the window class.
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = DemoApp::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = HINST_THISCOMPONENT;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = L"D2DDemoApp";
RegisterClassEx(&wcex);
// Because the CreateWindow function takes its size in pixels,
// obtain the system DPI and use it to scale the window size.
// The factory returns the current system DPI. This is also the value it will use
// to create its own windows.
Direct2DFactory->GetDesktopDpi(&dpiX, &dpiY);
// Create the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(1920.f * dpiX / 96.f)),
static_cast<UINT>(ceil(1080.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
/* OPENFILENAME data = {0};
wchar_t filename[256] = {0};
data.lpstrInitialDir = L"C:\\Users\\Billy\\Documents\\Calendarpic";
data.lStructSize = sizeof(data);
data.lpstrFile = filename;
data.nMaxFile = sizeof(filename);
data.hwndOwner = m_hwnd;
GetOpenFileName(&data);
IFileOpenDialog *data2;
*/
}
return hr;
}
// Creates resources that are not bound to a particular device.
// Their lifetime effectively extends for the duration of the
// application.
HRESULT DemoApp::CreateDeviceIndependentResources()
{
HRESULT hr = S_OK;
D2D1_FACTORY_OPTIONS options;
ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
// Create a Direct2D factory.
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory1), &options, reinterpret_cast<void **>(&Direct2DFactory));
if(SUCCEEDED(hr))
{
hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&ImageFactory)
);
}
return hr;
}
// Creates resources that are bound to a particular
// Direct3D device. These resources need to be recreated
// if the Direct3D device dissapears, such as when the display
// changes, the window is remoted, etc.
HRESULT DemoApp::CreateDeviceResources()
{
HRESULT hr = S_OK;
if (!Screen)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// Create a Direct2D render target.
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
ID3D11Device *device;
ID3D11DeviceContext *context;
D3D_FEATURE_LEVEL returnedFeatureLevel;
hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION,
&device, &returnedFeatureLevel, &context);
if(SUCCEEDED(hr))
{
hr = device->QueryInterface(__uuidof(ID3D11Device1), (void **)&Direct3DDevice);
}
if(SUCCEEDED(hr))
{
hr = context->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&Direct3dContext);
}
if(SUCCEEDED(hr))
{
hr = Direct3DDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
}
if(SUCCEEDED(hr))
{
hr = Direct2DFactory->CreateDevice(dxgiDevice, &Direct2DDevice);
}
if(SUCCEEDED(hr))
{
hr = Direct2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &Screen);
}
if(SUCCEEDED(hr))
{
hr = dxgiDevice->GetAdapter(&dxgiAdapter);
}
if(SUCCEEDED(hr))
{
hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
}
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
swapChainDesc.Width = 0;
swapChainDesc.Height = 0;
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.Stereo = false;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = 0;
if(SUCCEEDED(hr))
{
hr = dxgiFactory->CreateSwapChainForHwnd(Direct3DDevice, m_hwnd, &swapChainDesc, nullptr, nullptr, &DXGISwapChain);
}
if(SUCCEEDED(hr))
{
hr = DXGISwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));
}
if (SUCCEEDED(hr))
{
hr = CreateGridPatterBrush(Screen,&pGridPatternBitmapBrush);
}
D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), dpiX, dpiY);
if (SUCCEEDED(hr))
{
// Create a gray brush.
hr = Screen->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::LightSlateGray),
&m_pLightSlateGrayBrush
);
}
if (SUCCEEDED(hr))
{
// Create a blue brush.
hr = Screen->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
&m_pCornflowerBlueBrush
);
}
if(SUCCEEDED(hr))
{
hr = LoadBitmapFromFile(Screen,
ImageFactory,
L"C:\\Users\\Billy\\Documents\\Calendarpic\\CalendarBaseAqua.bmp",
1920,
1080,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
hr = CreateGridPatterBrush(Screen, &pGridPatternBitmapBrush);
}
Screen->SetTarget(Direct2DBackBuffer);
SafeRelease(&dxgiBackBuffer);
SafeRelease(&dxgiFactory);
SafeRelease(&dxgiAdapter);
SafeRelease(&dxgiDevice);
SafeRelease(&context);
SafeRelease(&device);
}
return hr;
}
HRESULT DemoApp::CreateGridPatterBrush(
ID2D1DeviceContext *pRenderTarget,
ID2D1BitmapBrush **ppBitmapBrush
)
{
// Create a compatible render target.
ID2D1BitmapRenderTarget *pCompatibleRenderTarget = NULL;
HRESULT hr = pRenderTarget->CreateCompatibleRenderTarget(
D2D1::SizeF(1920.0f, 1080.0f),
&pCompatibleRenderTarget
);
if (SUCCEEDED(hr))
{
// Draw a pattern.
ID2D1SolidColorBrush *pGridBrush = NULL;
hr = pCompatibleRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF(0.93f, 0.94f, 0.96f, 1.0f)),
&pGridBrush
);
if (SUCCEEDED(hr))
{
pCompatibleRenderTarget->BeginDraw();
pCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 0.0f, 10.0f, 1.0f), pGridBrush);
pCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 0.1f, 1.0f, 10.0f), pGridBrush);
pCompatibleRenderTarget->EndDraw();
// Retrieve the bitmap from the render target.
ID2D1Bitmap *pGridBitmap = NULL;
hr = pCompatibleRenderTarget->GetBitmap(&pGridBitmap);
if (SUCCEEDED(hr))
{
// Choose the tiling mode for the bitmap brush.
D2D1_BITMAP_BRUSH_PROPERTIES brushProperties =
D2D1::BitmapBrushProperties(D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);
// Create the bitmap brush.
hr = Screen->CreateBitmapBrush(pGridBitmap, brushProperties, ppBitmapBrush);
pGridBitmap->Release();
}
pGridBrush->Release();
}
pCompatibleRenderTarget->Release();
}
return hr;
}
// Discards device-dependent resources. These resources must be
// recreated when the Direct3D device is lost.
void DemoApp::DiscardDeviceResources()
{
SafeRelease(&Screen);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
SafeRelease(&Direct2DBackBuffer);
SafeRelease(&DXGISwapChain);
SafeRelease(&Direct2DDevice);
SafeRelease(&Direct3dContext);
SafeRelease(&Direct3DDevice);
}
// Runs the main window message loop.
void DemoApp::RunMessageLoop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// This method discards device-specific
// resources if the Direct3D device dissapears during execution and
// recreates the resources the next time it's invoked.
HRESULT DemoApp::OnRender()
{
HRESULT hr = S_OK;
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
Screen->BeginDraw();
Screen->SetTransform(D2D1::Matrix3x2F::Identity());
Screen->Clear(D2D1::ColorF(D2D1::ColorF::White));
D2D1_SIZE_F rtSize = Screen->GetSize();
Screen->DrawBitmap(pBitmap,
D2D1::RectF(0.0f, 0.0f, 1920, 1080));
// Draw a grid background.
int width = static_cast<int>(rtSize.width);
int height = static_cast<int>(rtSize.height);
hr = Screen->EndDraw();
DXGI_PRESENT_PARAMETERS parameters = { 0 };
parameters.DirtyRectsCount = 0;
parameters.pDirtyRects = nullptr;
parameters.pScrollRect = nullptr;
parameters.pScrollOffset = nullptr;
hr = DXGISwapChain->Present1(1, 0, ¶meters);
}
if (hr == D2DERR_RECREATE_TARGET)
{
hr = S_OK;
DiscardDeviceResources();
}
return hr;
}
// If the application receives a WM_SIZE message, this method
// resizes the render target appropriately.
void DemoApp::OnResize(UINT width, UINT height)
{
if (Screen)
{
// 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.
}
}
// Handles window messages.
LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
if (message == WM_CREATE)
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;
::SetWindowLongPtrW(
hwnd,
GWLP_USERDATA,
PtrToUlong(pDemoApp)
);
result = 1;
}
else
{
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pDemoApp)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
}
result = 0;
wasHandled = true;
break;
case WM_DISPLAYCHANGE:
{
InvalidateRect(hwnd, NULL, FALSE);
}
result = 0;
wasHandled = true;
break;
case WM_PAINT:
{
pDemoApp->OnRender();
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;
}
#包括“DemoApp.h”
//提供应用程序入口点。
int-WINAPI-WinMain(
HINSTANCE/*HINSTANCE*/,,
HINSTANCE/*hPrevInstance*/,,
LPSTR/*lpCmdLine*/,,
int/*nCmdShow*/
)
{
//使用HeapSetInformation指定进程应
//如果堆管理器在使用的任何堆中检测到错误,则终止
//通过这个过程。
//返回值被忽略,因为我们希望继续在
//HeapSetInformation失败的不太可能的事件。
HeapSetInformation(NULL,heapineableterminationoncorruption,NULL,0);
如果(成功(协同初始化(NULL)))
{
{
DemoApp应用程序;
如果(成功(app.Initialize()))
{
app.RunMessageLoop();
}
}
coninitialize();
}
返回0;
}
//DemoApp构造函数
DemoApp::DemoApp():
m_hwnd(空),
Direct2D工厂(空),
屏幕(空),
m_pLightSlateGrayBrush(空),
m_pCornflowerBlueBrush(空),
DXG设备(空),
dxgiAdapter(空),
DXG工厂(空),
Direct3DDevice(空),
Direct3dContext(空),
Direct2D设备(空),
DXGISwapChain(空),
Direct2DBBackBuffer(空)
{
}
//DemoApp析构函数
//释放应用程序的资源。
DemoApp::~DemoApp()
{
安全释放(&Direct2DFactory);
安全释放(和屏幕);
安全释放(&m_plightslategraysbrush);
安全释放(&m_pCornflowerBlueBrush);
}
HRESULT DemoApp::LoadBitmapFromFile(ID2D1DeviceContext*pRenderTarget,
IwicingFactory2*pIWICFactory,
PCWSTR uri,
单位目标宽度,
目的地高度,
ID2D1Bitmap1**ppBitmap
)
{
IWICBitmapDecoder*pDecoder=NULL;
IWICBitmapFrameDecode*pSource=NULL;
IWICStream*pStream=NULL;
IWICFormatConverter*pConverter=NULL;
IWICBitmapScaler*pScalar=NULL;
HRESULT hr=pIWICFactory->CreateDecoderFromFilename(
乌里,
无效的
泛读,
WicDecodataCacheOnLoad,
&光电编码器
);
如果(成功(hr))
{
hr=pDecoder->GetFrame(0,&pSource);
}
如果(成功(hr))
{
hr=pIWICFactory->CreateFormatConverter(&pConverter);
}
如果(成功(hr))
{
hr=pConverter->初始化(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
无效的
0.0f,
WICBitmapPaletteTypeMedianCut
);
}
如果(成功(hr))
{
hr=pRenderTarget->CreateBitmapFromWicBitmap(
转换程序,
无效的
PP位图
);
}
安全释放(&pDecoder);
安全释放(&pSource);
安全释放(&pStream);
安全释放装置(和转换装置);
安全释放(&pScalar);
返回人力资源;
}
void DemoApp::OpenFilePicker()
{
}
//创建与设备无关的应用程序窗口
//资源。
HRESULT DemoApp::初始化()
{
HRESULT-hr;
//初始化设备相关资源,例如
//作为Direct2D工厂。
hr=CreateDeviceIndependentResources();
如果(成功(hr))
{
//注册窗口类。
WNDCLASSEX wcex={sizeof(WNDCLASSEX)};
wcex.style=CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc=DemoApp::WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=sizeof(LONG_PTR);
wcex.hInstance=HINST_此组件;
wcex.hbrBackground=NULL;
wcex.lpszMenuName=NULL;
wcex.hCursor=LoadCursor(空,IDI_应用程序);
wcex.lpszClassName=L“D2DDemoApp”;
注册类别(&wcex);
//因为CreateWindow函数的大小以像素为单位,
//获取系统DPI并使用它缩放窗口大小。
//工厂返回当前系统DPI。这也是它将使用的值
//创建自己的窗口。
Direct2DFactory->GetDesktopDpi(&dpiX,&dpiY);
//创建窗口。
m_hwnd=CreateWindow(
L“D2DDemoApp”,
L“Direct2D演示应用程序”,
WS_重叠窗口,
CW_使用默认值,
CW_使用默认值,
静态铸造(ceil(1920.f*dpiX/96.f)),
静态铸造(ceil(1080.f*dpiY/96.f)),
无效的
无效的
HINST_这个组件,
这
);
hr=m_hwnd?S_OK:E_FAIL;
如果(成功(hr))
{
显示窗口(m_hwnd、SW_SHOWNORMAL);
更新域(m_hwnd);
}
/*OPENFILENAME数据={0};
wchar_t filename[256]={0};
data.lpstrInitialDir=L“C:\\Users\\Billy\\Documents\\Calendarpic”;
data.lsstructsize=sizeof(数据);
data.lpstrFile=文件名;
data.nMaxFile=sizeof(文件名);
data.hwndOwner=m_hwnd;
GetOpenFileName(&data);
IFileOpenDialog*数据2;
*/
}
返回人力资源;
}
//创建未绑定到特定设备的资源。
//它们的寿命有效地延长了整个生命周期
//应用程序。
HRESULT DemoApp::CreateDeviceIndependentResources()
{
HRESULT hr=S_正常;
D2D1_工厂_选项;
零内存(&options,sizeof(D2D1工厂选项));
//创建Direct2D工厂。
hr=D2D1CreateFactory(D2D1工厂类型单线程、ID2D1Factory1和选项、重新解释转换(&Direct2DFactory));
如果(成功(hr))
{
hr=CoCreateInstance(
CLSID_Wicimaging工厂,