在0x00f85069获取未处理的异常

时间:2010-11-20 23:08:40

标签: c++ winapi visual-c++

我的节目中断了并且说了这个

Unhandled exception at 0x00f85069 in Monopoly.exe: 0xC0000005: Access violation writing location 0x0000000c.

我做了一个win32包装器。我有两个WndProc一个是静态而另一个不是。静态WndProc调用非静态WndProc。当我尝试获取消息时它工作正常,但是当我尝试为某些东西设置值时会抛出异常 这是我的两个WndProc的代码(第一个是静态的)

LRESULT CALLBACK Window::StaticWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) 
{ 
   if ( msg == WM_CREATE ) 
   { 
       SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG)((CREATESTRUCT *)lParam)->lpCreateParams ); 
   }
   Window *targetApp = (Window*)GetWindowLongPtr( hWnd, GWLP_USERDATA );

   return targetApp->WndProc( hWnd, msg, wParam, lParam ); 
}

LRESULT CALLBACK Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_PAINT:
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_LBUTTONDOWN:
        z=-14; //IT THROW EXCEPTION
        break;
    case WM_RBUTTONDOWN:
        z-=1;
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

先谢谢

修改
VARABILES
int z;

3 个答案:

答案 0 :(得分:1)

嗯,访问冲突(0xC0000005)意味着你访问了你不应该拥有的内存。在这种情况下,它表示您正在尝试写入0x0000000c。既然你(你的调试器?)说z的赋值导致它,我们可以看到那个符号的定义吗?此外,它真的是z = -14还是z -= 14

编辑:我认为您需要使用指向((CREATESTRUCT *)lParam)->lpCreateParams实例的有效指针替换class Window

编辑#2:会发生什么:在WM_CREATE上,您将GWLP_USERDATA设置为恰好等于NULL的值。随后,您通过在该指针上调用非静态成员函数来读取该值并将其视为指向Window的有效指针。类成员函数由编译器实现实现

LRESULT CALLBACK <mangled_name ("Window::WndProc")> (Window * const this, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    // ...
}

这就是你可以在NULL指针上实际调用成员函数的原因。但是,一旦访问成员变量,例如z,就会中断。编译器插入的代码类似于*((int*) (this + 0xc)) = -14,(BT​​W意味着z位于Window实例中的0xc字节),自this == NULL以来,它已经破坏。

答案 1 :(得分:1)

您正在调用WndProc的对象似乎不存在(null?),并且在尝试在z -= 14中写入内存时遇到访问冲突,this->z -= 14 }(this是无效指针)。这是我的猜测。

此外,访问冲突在C ++术语中也不例外。 :)

答案 2 :(得分:1)

你是如何创建窗口的?您是否通过Window参数向CreateWindow()CreateWindowEx()函数传递了lpParam实例的有效指针?例如,如果您的窗口包装器具有Create()函数或类似的东西:

void Window::Create()
{
    /* ... */

    // Pass a pointer to ourselves to CreateWindow() via the lpParam parameter.
    // CreateWindow() then passes that pointer to your window procedure
    // (StaticWndProc) via WM_CREATE and WM_NCCREATE in the lpCreateParams member
    // of CREATESTRUCT. This way the window procedure will know which instance to
    // call WndProc() on.
    CreateWindow(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight,
        hWndParent, hMenu, hInstance, (LPVOID)this);

    /* ... */
}
相关问题