Внедренная DLL с использованием GDI + вызывает сбой Блокнота - PullRequest
0 голосов
/ 23 ноября 2010

У меня есть решение 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 Explorer аварийно завершают работу (окно Windows Explorer находится в отдельном процессе от оболочки Windows Explorer).

Спасибо!

1 Ответ

4 голосов
/ 23 ноября 2010

Уверен, что это следующая строка

 delete &graphics;

, который заставляет ваш код взорваться. delete следует использовать только в том случае, если указатель был получен с помощью new, здесь вы даете ему что-то в стеке. Вызывать delete для выделенной переменной стека не имеет смысла.

Чтобы убедиться, что экземпляр Graphics уничтожен до вызова GdiplusShutdown, вы можете ввести новую область действия:

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