使用GDI +注入的DLL会导致记事本崩溃

时间:2010-11-23 01:40:49

标签: c++ crash gdi+ hook

我有一个Visual Studio解决方案,它包含一个DLL和一个EXE。我的程序设置了一个全局WH_CALLWNDPROC钩子。钩子过程由DLL定义。我已经验证DLL被正确地注入到我感兴趣的所有进程中.DLL导出一些过程,这些过程在头文件中定义,而不是在DEF文件中定义。 EXE自动加载DLL并调用DLL中的方法来设置钩子。加载DLL时,DllMain设置一个内部HMODULE变量,其中包含DLL的模块句柄。当EXE调用installHook过程时,DLL会设置挂钩。这一切都很好。

当我的钩子程序收到WM_SIZING消息时,它会执行另一个内部程序,该程序应该使用GDI +在窗口的客户端DC上绘制一些内容。使用标准GDI工作。但是,GDI +(我需要使用)不起作用:Graphics::Graphics(HDC)构造函数会在我尝试调整窗口大小时导致任何程序崩溃。以下是导致崩溃的代码片段:

void myFaultyProcedure(HWND hWnd) {
    RECT wndRect;
    GetWindowRect(hWnd,&wndRect);
    unsigned int wndWidth=wndRect.right-wndRect.left;
    unsigned int wndHeight=wndRect.bottom-wndRect.top;
    HDC hDc;
    PAINTSTRUCT ps;
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL);
    hDc=BeginPaint(hWnd,&ps);
    Graphics graphics(hDc); // I think that this causes the program to crash
    delete &graphics;
    EndPaint(hWnd,&ps);
    ReleaseDC(hWnd,hDc);
    GdiplusShutdown(gdiplusToken);
}

代码计算给定窗口的宽度和高度,获取DC,启动GDI +,创建Graphics对象,删除Graphics对象,释放DC,然后关闭GDI +。我无法想象为什么程序会因为这些行而崩溃。记事本和Windows资源管理器都崩溃了(Windows资源管理器窗口与Windows资源管理器Shell在一个单独的进程中)。

谢谢!

1 个答案:

答案 0 :(得分:4)

很确定这是下一行

 delete &graphics;

这会让你的代码爆炸。 delete只应在指针由new获得的情况下使用,这里你在堆栈上给它一些东西。在堆栈分配变量上调用delete是没有意义的。

要确保在调用GdiplusShutdown之前销毁Graphics实例,您可以引入一个新范围:

{
   Graphics g(...);
   g.DoStuff();
   ...
} // g is destroyed here
GdiplusShutdown(...)