C++ 在0x0131EB06 Visual Studio上引发异常

C++ 在0x0131EB06 Visual Studio上引发异常,c++,visual-studio,direct2d,C++,Visual Studio,Direct2d,我是Directx的新手,我想测试一个在窗口中画圆圈的简单direct2d应用程序。我正在使用Visual Studio Professional。当我使用本地Windows调试器运行名为D2D测试引擎的程序时,会出现以下错误: Exception thrown at 0x0140EB06 in D2D Test Engine.exe: 0xC0000005: Access violation reading location 0x00000008. Exception thrown at 0x

我是Directx的新手,我想测试一个在窗口中画圆圈的简单direct2d应用程序。我正在使用Visual Studio Professional。当我使用本地Windows调试器运行名为D2D测试引擎的程序时,会出现以下错误:

Exception thrown at 0x0140EB06 in D2D Test Engine.exe: 0xC0000005: Access violation reading location 0x00000008.
Exception thrown at 0x0140EB06 in D2D Test Engine.exe: 0xC0000005: Access violation reading location 0x00000008.
Exception thrown at 0x0140EB06 in D2D Test Engine.exe: 0xC0000005: Access violation reading location 0x00000008.
我想不出我的程序出了什么问题。 这是我的密码:

#include <Windows.h>
#include "Graphics.h"
Graphics* graphics;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (uMsg == WM_DESTROY) {
    PostQuitMessage(0);
    return 0;
}
graphics->BeginDraw();
graphics->ClearScreen(0.0f, 0.0f, 0.5f);
graphics->DrawShape(100, 100, 50, 1.0f, 0.0, 0.0, 1.0);
graphics->EndDraw();
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow) {
WNDCLASSEX windowclass;
ZeroMemory(&windowclass, sizeof(WNDCLASSEX));
windowclass.cbSize = sizeof(WNDCLASSEX);
windowclass.hbrBackground = (HBRUSH) COLOR_WINDOW;
windowclass.hInstance = hInstance;
windowclass.lpfnWndProc = WindowProc;
windowclass.lpszClassName = "MainWindow";
windowclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&windowclass);
RECT rect = { 0, 0, 800, 600 };
AdjustWindowRectEx(&rect, WS_EX_OVERLAPPEDWINDOW, false, WS_EX_OVERLAPPEDWINDOW);
HWND windowHandle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MainWindow", "D2D Test Engine", WS_OVERLAPPEDWINDOW, 0, 0, rect.right - rect.left,      rect.bottom - rect.top, NULL, NULL, hInstance, 0);
    if (!windowHandle) {
        return -1;
    }
    graphics = new Graphics();
    if (graphics->Init(windowHandle) == false) {
        delete graphics;
        return -1;
    }
    ShowWindow(windowHandle, nCmdShow);
    MSG message;
    while (GetMessage(&message, NULL, 0, 0)) {
        DispatchMessage(&message);
    }
    return 0;
}
#包括
#包括“Graphics.h”
图形*图形;
LRESULT回调WindowProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM){
如果(uMsg==WM_){
PostQuitMessage(0);
返回0;
}
图形->BeginDraw();
图形->透明屏幕(0.0f、0.0f、0.5f);
图形->DrawShape(100,100,50,1.0f,0.0,0.0,1.0);
图形->EndDraw();
返回DefWindowProc(hwnd、uMsg、wParam、lParam);
}
int WINAPI wWinMain(HINSTANCE HINSTANCE、HINSTANCE prevInstance、LPWSTR cmd、int nCmdShow){
WNDCLASSEX窗口类;
零内存(&windowclass,sizeof(WNDCLASSEX));
windowclass.cbSize=sizeof(WNDCLASSEX);
windowclass.hbrBackground=(HBRUSH)颜色窗口;
windowclass.hInstance=hInstance;
windowclass.lpfnWndProc=WindowProc;
windowclass.lpszClassName=“MainWindow”;
windowclass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&windowclass);
RECT RECT={0,0800600};
AdjustWindowRectEx(&rect,WS_-EX_-OVERLAPPEDWINDOW,false,WS_-EX_-OVERLAPPEDWINDOW);
HWND windowHandle=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,“主窗口”,“D2D测试引擎”,WS_OVERLAPPEDWINDOW,0,0,rect.right-rect.left,rect.bottom-rect.top,NULL,NULL,hInstance,0);
如果(!windowHandle){
返回-1;
}
图形=新图形();
如果(图形->初始化(windowHandle)==false){
删除图形;
返回-1;
}
ShowWindow(windowHandle,nCmdShow);
消息;
while(GetMessage(&message,NULL,0,0)){
DispatchMessage(&message);
}
返回0;
}
下一个文件:

#pragma once
#include <Windows.h>
#include <d2d1.h>
class Graphics
{
ID2D1Factory* factory;
ID2D1HwndRenderTarget* renderTarget;
public:
Graphics();
virtual ~Graphics();
bool Init(HWND windowHandle);
void BeginDraw() {renderTarget->BeginDraw();}
void EndDraw() {renderTarget->EndDraw();}
void ClearScreen(float r, float g, float b);
void DrawShape(float x, float y, float radius, float r, float g, float b, float a);
};
#include "Graphics.h"
#include <d2d1.h>
#include <Windows.h>
Graphics::Graphics()
{
factory = NULL;
renderTarget = NULL;
}
Graphics::~Graphics()
{
if (factory) {
    factory->Release();
}
if (renderTarget) {
    renderTarget->Release();
}
}
bool Graphics::Init(HWND windowHandle) {
HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &factory);
if (res != S_OK) {
    return false;
}
RECT rect;
GetClientRect(windowHandle, &rect);
res = factory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(windowHandle, D2D1::SizeU(rect.right, rect.bottom)), &renderTarget);
if (res != S_OK) {
    return false;
}
return true;
}
void Graphics::ClearScreen(float r, float g, float b) {
renderTarget->Clear(D2D1::ColorF(r, g, b));
}
void Graphics::DrawShape(float x, float y, float radius, float r, float g, float b, float a) {
ID2D1SolidColorBrush* brush;

renderTarget->CreateSolidColorBrush(D2D1::ColorF(r, g, b, a), &brush);
renderTarget->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(x, y), radius, radius), brush, 3.0f);
brush->Release();
}
#pragma一次
#包括
#包括
类图形
{
ID2D1Factory*工厂;
ID2D1HwndRenderTarget*渲染目标;
公众:
图形();
虚拟图形();
bool Init(HWND windowHandle);
void BeginDraw(){renderTarget->BeginDraw();}
void EndDraw(){renderTarget->EndDraw();}
空隙清除屏(浮子r、浮子g、浮子b);
空心拉伸形状(浮子x、浮子y、浮子半径、浮子r、浮子g、浮子b、浮子a);
};
下一个文件:

#pragma once
#include <Windows.h>
#include <d2d1.h>
class Graphics
{
ID2D1Factory* factory;
ID2D1HwndRenderTarget* renderTarget;
public:
Graphics();
virtual ~Graphics();
bool Init(HWND windowHandle);
void BeginDraw() {renderTarget->BeginDraw();}
void EndDraw() {renderTarget->EndDraw();}
void ClearScreen(float r, float g, float b);
void DrawShape(float x, float y, float radius, float r, float g, float b, float a);
};
#include "Graphics.h"
#include <d2d1.h>
#include <Windows.h>
Graphics::Graphics()
{
factory = NULL;
renderTarget = NULL;
}
Graphics::~Graphics()
{
if (factory) {
    factory->Release();
}
if (renderTarget) {
    renderTarget->Release();
}
}
bool Graphics::Init(HWND windowHandle) {
HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &factory);
if (res != S_OK) {
    return false;
}
RECT rect;
GetClientRect(windowHandle, &rect);
res = factory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(windowHandle, D2D1::SizeU(rect.right, rect.bottom)), &renderTarget);
if (res != S_OK) {
    return false;
}
return true;
}
void Graphics::ClearScreen(float r, float g, float b) {
renderTarget->Clear(D2D1::ColorF(r, g, b));
}
void Graphics::DrawShape(float x, float y, float radius, float r, float g, float b, float a) {
ID2D1SolidColorBrush* brush;

renderTarget->CreateSolidColorBrush(D2D1::ColorF(r, g, b, a), &brush);
renderTarget->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(x, y), radius, radius), brush, 3.0f);
brush->Release();
}
#包括“Graphics.h”
#包括
#包括
Graphics::Graphics()
{
factory=NULL;
renderTarget=NULL;
}
图形::~Graphics()
{
if(工厂){
工厂->发布();
}
如果(渲染目标){
renderTarget->Release();
}
}
bool图形::Init(HWND windowHandle){
HRESULT res=D2D1CreateFactory(D2D1工厂类型多线程和工厂);
如果(res!=S_OK){
返回false;
}
RECT-RECT;
GetClientRect(windowHandle,&rect);
res=factory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),D2D1::HwndRenderTargetProperties(windowHandle,D2D1::SizeU(rect.right,rect.bottom)),&renderTarget);
如果(res!=S_OK){
返回false;
}
返回true;
}
无效图形::清除屏幕(浮动r、浮动g、浮动b){
renderTarget->Clear(D2D1::ColorF(r,g,b));
}
空心图形::DrawShape(浮动x、浮动y、浮动半径、浮动r、浮动g、浮动b、浮动a){
ID2D1SOLIDCORBRUSH*电刷;
renderTarget->CreateSolidColorBrush(D2D1::ColorF(r、g、b、a)和笔刷);
renderTarget->Drumellipse(D2D1::Ellipse(D2D1::Point2F(x,y),半径,半径),笔刷,3.0f);
刷->释放();
}

当我不调用BeginDraw()、ClearScreen、DrawShape和EndDraw时,会出现一个窗口,它运行正常,所以我认为这与它们有关。

看来,您对消息有问题。 调用CreateWindowEx时发送此消息

Graphics* graphics = NULL; // it's better to zero pointer in C++.
简单解决方案-将图形设置为null,并在WindowProc函数中进行检查

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_DESTROY) {
      PostQuitMessage(0);
      return 0;
   } 

   if (graphics) {
     graphics->BeginDraw();
     graphics->ClearScreen(0.0f, 0.0f, 0.5f);
     graphics->DrawShape(100, 100, 50, 1.0f, 0.0, 0.0, 1.0);
     graphics->EndDraw();
   }
   return DefWindowProc(hwnd, msg, wParam, lParam);
}

我找到了答案。我对directx这个东西还很陌生,我用了一个教程来构建它。我需要做的是将我调用的所有函数放入if语句中。以下是我所做的:

if (uMsg == WM_PAINT) {
    graphics->BeginDraw();
    graphics->ClearScreen(0.0f, 0.0f, 0.5f);
    graphics->DrawShape(100, 100, 50, 1.0f, 0.0, 0.0, 1.0);
    graphics->EndDraw();
}

很抱歉给您添了这么多麻烦,我是新来的。

我猜您在某处有
NULL
指针访问权限。您应该在调试器中运行,并让调试器在崩溃位置停止。请使用调试器。几乎可以肯定是一个空指针,您可以通过它访问结构成员。请格式化/缩进代码以提高可读性。调试器在void BeginDraw(){renderTarget->BeginDraw();}处停止。好的,所以当我创建objects方法时,我将其设置为空?还有,你说的检查是什么意思?我应该在WindowProc函数中做什么?我已经更新了我的帖子。您还可以阅读有关OpenGL和window proc的文章。您可以处理WM_激活消息并设置可以渲染的布尔标志。而且,作为改进,您应该避免使用go全局变量并传递指针对不起,可以直接回答您的消息,但WM_PAINT不是游戏的好解决方案,它可能会降低fps。那么有没有建议替换WM_PAINT?最佳方式-模式渲染到其他线程,并在窗口和上下文初始化后在循环中绘制场景,只是计算帧时间,并可能限制它。从主线程只需设置标志,如果渲染应该是活动的(窗口激活和停用)。你应该阅读这篇关于游戏编程模式的文章。