2010-11-23 20 views
0

J'ai une solution Visual Studio composée d'une DLL et d'un fichier EXE. Mon programme définit un crochet WH_CALLWNDPROC global. La procédure de hook est définie par la DLL. J'ai vérifié que la DLL est correctement injectée dans tous les processus qui m'intéressent. La DLL exporte quelques procédures, qui sont définies dans un fichier d'en-tête, et non dans un fichier DEF. Le fichier EXE charge automatiquement la DLL et appelle une méthode dans la DLL pour définir le hook. Lorsque la DLL est chargée, DllMain définit une variable interne HMODULE qui contient le handle de module de la DLL. Lorsque l'EXE appelle la procédure installHook, la DLL définit le hook. Tout cela fonctionne bien.La DLL injectée à l'aide de GDI + provoque le plantage du Bloc-notes

Lorsque ma procédure de connexion reçoit un message WM_SIZING, elle exécute une autre procédure interne, supposée utiliser GDI + pour dessiner quelque chose sur le client DC de la fenêtre. Utilisation des travaux GDI standard. Cependant, GDI + (que j'ai besoin d'utiliser) ne fonctionne pas: le constructeur Graphics::Graphics(HDC) fait planter n'importe quel programme dès que j'essaye de redimensionner la fenêtre. Voici un extrait du code qui provoque l'accident:

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

Le code calcule la largeur et la hauteur d'une fenêtre donnée, obtient un DC, commence GDI +, crée un objet graphique, supprime l'objet Graphics, libère le DC, et arrête GDI +. Je ne peux pas imaginer pourquoi les programmes se bloqueraient à cause de ces lignes. Bloc-notes et l'Explorateur Windows tous les deux se brisent (la fenêtre de l'Explorateur Windows est dans un processus distinct de l'environnement de l'Explorateur Windows).

Merci!

Répondre

4

sûr qu'il est la ligne suivante

delete &graphics; 

qui rend votre code Carnaby. delete ne doit être utilisé que si le pointeur a été obtenu par new, ici vous lui donnez quelque chose sur la pile. Appeler supprimer sur une pile n'a pas de sens.

Pour veiller à ce que l'instance Graphics est détruit avant GdiplusShutdown est appelé, vous pouvez introduire une nouvelle portée:

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

+1 Eh bien repéré. – karlphillip

+0

Je ne suis pas très expérimenté dans ce domaine, alors merci! La documentation pour GDI + indique que GdiplusShutdown devrait être appelé après que tous les objets GDI + ont été supprimés ou sont sortis de la portée. Puisque GdiplusShutdown est appelé dans la même portée que la création de Graphics, j'ai pensé que l'opérateur delete devrait être utilisé. Que devrais-je faire alors - le laisserai-je travailler, et sera-t-il automatiquement désaffecté? – AniDev

+1

@Ani B J'ai mis à jour ma réponse pour savoir comment gérer cela. –