2014-06-27 1 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]; 
} 

Voici ma principale boucle de rappel, celui enregistré avec le WindowClass:violation d'accès sur un réseau privé à l'intérieur d'une classe

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

Enfin, au-dessous est le gestionnaire de message secondaire qui est une partie de mon 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); } 
    } 
} 

l'exception est déclenchée lorsque le code arrive à mon switch/case/liste par défaut dans le gestionnaire de message secondaire. Si je commente ces lignes, le programme fonctionne bien, mais bien sûr, pas d'entrée.

Toute aide ou aide serait précieuse. Merci beaucoup pour votre temps.

+0

Où la violation d'accès se produit-elle? Quel est le message complet? – user3344003

+2

Qu'est-ce qu'un message d'erreur complet? Insérer les parties manquantes: 'Violation d'accès emplacement

'.Après le point d'arrêt frappe votre code, regardez les variables et bientôt vous trouverez le problème. Si ce n'est pas le cas, parcourez la pile d'appels et observez les variables à chaque étape. Je suppose que c'est un pointeur non initialisé. – Drop

+0

Nous avons besoin de votre fichier d'en-tête. – ForNeVeR

Répondre

0

Essayez suite à la modification de votre code:

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

(puisque vous avez aucun problème dans le constructeur de InputClass, ce n'est pas un problème de statut privé du tableau)

0

Je l'ai essayé avec pas de chance. Je vais laisser le code juste en cas d'erreur, mais il a appelé une violation d'accès au même endroit.

Je vais inclure les informations manquantes ci-dessous.

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

Le message d'erreur donné quand quand je frappe la touche d'échappement: exception non gérée à 0x00881E08 dans DX11 Engine 2.exe: 0xC0000005: violation d'accès lecture emplacement 0x00000004.

OK: c'est là que ça devient intéressant, les valeurs du champ local (spécifique à la deuxième fonction de rappel) sont les suivantes: lparam: 65537 wparam: 27 messages : 256 hwnd: 0x01b80460 {utilisé = ???} ceci: 0x00000000

Les valeurs de hwnd, wparam et lparam sont toutes affichées en rouge. J'ai l'impression que les valeurs sont censées me dire quelque chose sur ce qui se passe ici, mais je ne comprends pas vraiment. Y a-t-il une raison pour laquelle la variable "this" est définie sur l'adresse 0x00000000? c'est un pointeur vers une instance de la classe système ... ou c'est supposé l'être.

Aussi, le commentaire inutilisé dans hwnd me rejette, bien que je ne sois pas sûr de ce qui ne va pas là car le programme est très clairement au moins DETECTER une touche attribuée à la fenêtre. J'espère que cela aidera n'importe qui avec des idées.

EDIT: Vous m'avez cherché un pointeur mal utilisé et j'ai découvert qu'il avait TOUT à faire avec le pointeur "this" et la façon dont j'utilisais systemHandle et ApplicationHandle. Je l'ai réparé en changeant ApplicationHandle au système et en utilisant simplement le même pointeur partout. La façon dont je l'utilisais auparavant était illogique et insensée.

Merci à tous de m'avoir aidé à le trouver!

Questions connexes