2014-06-27 70 views
0
For the most part this is borrowed code from RasterTeks DX11 tutorial that I am modified lightly or my own use and taste. I am getting a read access violation while using the below InputClass to set keystates. 

#include "InputClass.h" 

InputClass::InputClass() { } 
InputClass::InputClass(const InputClass& other) { } 
InputClass::~InputClass() { } 

void InputClass::Initialize() { 
    // Initialize all the keys to being released and not pressed. 
    for (int i = 0; i<256; i++) { 
     keystate[i] = false; 
    } 

    return; 
} 


void InputClass::KeyDown(unsigned int input) { 
    // If a key is pressed then save that state in the key array. 
    keystate[input] = true; 
    return; 
} 


void InputClass::KeyUp(unsigned int input) { 
    // If a key is released then clear that state in the key array. 
    keystate[input] = false; 
    return; 
} 


bool InputClass::IsKeyDown(unsigned int input) { 
    // Return what state the key is in (pressed/not pressed). 
    return keystate[input]; 
} 

下面內部的專用陣列上是我的主要的回調循環中,一個與WindowClass註冊:訪問衝突一類

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:

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); } 
    } 
} 

當代碼到達輔助消息處理程序中我的switch/case/default列表時,會觸發異常。如果我將這些線條評論出來,程序可以愉快地運行,但當然不會有任何輸入。

任何幫助或線索將是無價的。非常感謝您的參與。下面的代碼進行修改

+0

訪問衝突發生在哪裏?什麼是完整的信息? – user3344003

+2

什麼是完整的錯誤信息?插入缺少的部分:'訪問衝突<讀/寫/執行>位置

'。斷點擊中你的代碼後,觀察變量,很快你會發現問題。如果沒有,請在每個步驟中遍歷調用堆棧並觀察變量。我想,這是未初始化的指針。 – Drop

+0

我們需要你的頭文件。 – ForNeVeR

回答

0

嘗試:

void InputClass::KeyDown(unsigned int input) { 
    if (input < 0 || input > 255) 
     return; 
    // If a key is pressed then save that state in the key array. 
    keystate[input] = true; 
    return; 
} 

void InputClass::KeyUp(unsigned int input) { 
    if (input < 0 || input > 255) 
     return; 
    // If a key is released then clear that state in the key array. 
    keystate[input] = false; 
    return; 
} 

(因爲你有在InputClass構造沒有任何問題,這不是數組的私有狀態的問題)

0

我嘗試了用沒有運氣。我會在出現錯誤的情況下保留代碼,但它會在同一地方調用訪問衝突。

我會在下面列出缺少的信息。

//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更改爲系統並在每個地方簡單地使用相同的指針來修復它。我以前使用它的方式是不合邏輯和毫無意義的。

謝謝大家幫助我找到它!