我嘗試了用沒有運氣。我會在出現錯誤的情況下保留代碼,但它會在同一地方調用訪問衝突。
我會在下面列出缺少的信息。
//inputclass.h
class InputClass
{
public:
InputClass();
InputClass(const InputClass&);
~InputClass();
void Initialize();
void KeyDown(unsigned int);
void KeyUp(unsigned int);
bool IsKeyDown(unsigned int);
//private:
bool keystate[256];
};
//systemclass.h
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <windowsx.h>
#include "InputClass.h"
class SystemClass {
public:
SystemClass();
~SystemClass();
void Startup();
bool InitializeWindows(HWND);
void ShutDown();
void Run();
LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
int GetWindowPosX();
int GetWindowPosY();
int GetWindowWidth();
int GetWindowHeight();
private:
HWND hWnd;
InputClass* input;
int posX, posY, windowWidth, windowHeight;
};
static SystemClass* ApplicationHandle = 0;
//main.cpp
#include "systemclass.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreviousInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
SystemClass* system;
system = new SystemClass;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"Engine";
RegisterClassEx(&wc);
system->Startup();
if(!(system->InitializeWindows(CreateWindowEx(NULL,
L"Engine",
L"Engine",
WS_POPUP | WS_VISIBLE,
system->GetWindowPosX(),
system->GetWindowPosY(),
system->GetWindowWidth(),
system->GetWindowHeight(),
NULL,
NULL,
hInstance,
NULL)))) return 0;
system->Run();
system->ShutDown();
UnregisterClass(L"Engine", hInstance);
delete system;
system = 0;
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
// this message is read when the window is closed
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
// Check if the window is being closed.
case WM_CLOSE: {
PostQuitMessage(0);
return 0;
}
default: { return ApplicationHandle->MessageHandler(hWnd, message, wParam, lParam); }
}
}
//systemclass.cpp
#include "SystemClass.h"
SystemClass::SystemClass() { }
SystemClass::~SystemClass() { }
void SystemClass::Startup() {
ApplicationHandle = this;
windowWidth = GetSystemMetrics(SM_CXSCREEN);
windowHeight = GetSystemMetrics(SM_CYSCREEN);
input = new InputClass;
input->Initialize();
int fc = MessageBox(NULL, L"Engine", L"Fullscreen?", MB_YESNO);
switch (fc) {
case 7: {
posX = (windowWidth - 800)/2;
posY = (windowHeight - 600)/2;
windowWidth = 800;
windowHeight = 600;
}
case 6: {
DEVMODE dmScreenSettings;
posX = posY = 0;
ZeroMemory(&dmScreenSettings, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long)windowWidth;
dmScreenSettings.dmPelsHeight = (unsigned long)windowHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Change the display settings to full screen.
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
}
}
}
bool SystemClass::InitializeWindows(HWND ihWnd) {
hWnd = ihWnd;
if (hWnd) {
//system->InitializeWindows(hWnd);
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
return true;
}
else {
MessageBoxEx(NULL, L"Could not create window.", L"ERROR!", MB_OK | MB_ICONEXCLAMATION, NULL);
return false;
}
}
void SystemClass::ShutDown() {
delete input;
input = 0;
DestroyWindow(hWnd);
hWnd = NULL;
ApplicationHandle = NULL;
}
void SystemClass::Run() {
bool done;
MSG msg;
done = false;
while (!done) {
// Handle the windows messages.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (input->IsKeyDown(VK_ESCAPE)) {
done = true;
MessageBoxEx(NULL, L"input broken.", L"ERROR!", MB_OK | MB_ICONEXCLAMATION, NULL);
}
// If windows signals to end the application then exit out.
if (msg.message == WM_QUIT) { done = true; }
}
}
int SystemClass::GetWindowPosX(){ return posX; }
int SystemClass::GetWindowPosY() { return posY; }
int SystemClass::GetWindowWidth() { return windowWidth; }
int SystemClass::GetWindowHeight() { return windowHeight; }
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_KEYDOWN: { input->KeyDown((unsigned int)wparam); }
case WM_KEYUP: { input->KeyUp((unsigned int)wparam); }
default: { return DefWindowProc(hwnd, message, wparam, lparam); }
}
}
給予時,當我按下Esc鍵的錯誤消息:在DX11引擎2.exe在0x00881E08 未處理的異常:0000005:訪問衝突讀取位置0x00000004。
OK:這是它變得有趣,在本地區域(特定於第二回調函數)的值如下: LPARAM:65537 WPARAM:27 消息:256 HWND:0x01b80460 {未使用= ??? this:0x00000000
hwnd,wparam和lparam的值都以紅色顯示。
我覺得值都應該告訴我一些關於什麼是怎麼回事,但我真的不明白。是否有一個原因,爲什麼變量「this」設置爲地址0x00000000?這是一個指向系統類實例的指針......或者它應該是。
此外,在HWND未使用的評論引發了我了,雖然我不知道是怎麼回事錯在那裏,因爲該方案是很清楚檢測至少歸因於窗口按鍵。
我希望這可以幫助任何想法的人。
編輯:你讓我找一個誤用指針,我發現它有什麼都做的「this」指針和我所用的系統和ApplicationHandle的方式。我通過將ApplicationHandle更改爲系統並在每個地方簡單地使用相同的指針來修復它。我以前使用它的方式是不合邏輯和毫無意義的。
謝謝大家幫助我找到它!
訪問衝突發生在哪裏?什麼是完整的信息? – user3344003
什麼是完整的錯誤信息?插入缺少的部分:'訪問衝突<讀/寫/執行>位置
'。斷點擊中你的代碼後,觀察變量,很快你會發現問題。如果沒有,請在每個步驟中遍歷調用堆棧並觀察變量。我想,這是未初始化的指針。 – Drop我們需要你的頭文件。 – ForNeVeR