probleme beim subclassen von fenstern anderer prozesse
-
also, ich wollte mal die fenster eines anderen prozesses subclassen, und hab mir deshalb eine hook-dll geschrieben,die die tolle aufgabe hat zu warten bis das fenster ihrer anwendung aktiviert/deaktiviert wird, und dann entweder das aktivierte fenster +alle childs zu subclassen, oder das subclassing der fenster halt wieder aufzuheben. als test werden dann Aktiviert/deaktiviert nachrichten zu meiner application geschickt.
solange ich die childs nicht subclasse scheint es auch zu funktionieren(so ganz sicher bin ich mir da ja nicht...),wenn ich die childs aber mit subclasse funktionierts entweder wunderbar, oder windows beschwert sich, dass ich den explorer mal wieder habe abrauchen lassen
ich hab jetzt schon einige fehlerquellen beseitigen/ausschließen können, aber nun mit diesen sporadischen fehlern(fehler beim lesen von speicher...) komm ich nicht klar, und vielleicht seht ihrs ja auf den ersten blick.
der code ist quick'n'dirty, weils eigentlich nurn einfacher test sein sollte, aber ich denke, dass er nicht zu schlimm ausschaut:
//der hook callback selber LRESULT CALLBACK hookProc(int nCode,unsigned int wParam,unsigned int lParam){ //das aktuelle subclassed window static HWND subclassedWindow=0; if(nCode==HC_ACTION){ CWPRETSTRUCT* message=(CWPRETSTRUCT*)lParam; if(message->message==WM_ACTIVATE){ if(LOWORD(message->wParam)==WA_CLICKACTIVE||LOWORD(message->wParam)==WA_ACTIVE){ if(GetForegroundWindow()!=subclassedWindow){ //erst aufräumen if(subclassedWindow){ removeSubclass(subclassedWindow); } subclassedWindow=GetForegroundWindow(); subclass(subclassedWindow,messageTarget); } } else { //fenster wird inaktiv->subclass entfernen if(GetForegroundWindow()!=subclassedWindow){ removeSubclass(subclassedWindow); subclassedWindow=0; } } } } return CallNextHookEx (hook, nCode, wParam, lParam); }
//die funktionen subclass und removeSubclass void subclass(HWND window,HWND messageTarget){ SetProp(window,"oldProc",(HANDLE)SetWindowLong(window,GWL_WNDPROC,(long) subclassProc)); SetProp(window,"messageTarget",(HANDLE)messageTarget); PostMessage(messageTarget,US_PARENT,(LPARAM)window,0); InfoHolder info; info.parent=window; info.messageTarget=messageTarget; EnumChildWindows(window,(WNDENUMPROC)childSubclassProc,(unsigned int)&info); } void removeSubclass(HWND window){ HWND messageTarget=(HWND)GetProp(window,"messageTarget"); PostMessage(messageTarget,US_REMOVE,(LPARAM)window,0); long proc=(long)GetProp(window,"oldProc"); SetWindowLong(window,GWL_WNDPROC,proc); EnumChildWindows(window,(WNDENUMPROC)childRemoveSubclassProc,0); RemoveProp(window,"oldProc"); RemoveProp(window,"messageTarget"); }
//die subclass Prozedur long subclassProc(HWND window,unsigned int message, unsigned int wParam,unsigned int lParam){ switch(message){ case WM_NCDESTROY: { removeSubclass(window); } } return CallWindowProc((WNDPROC)GetProp(window,"oldProc"),window,message,wParam,lParam); }
//die prozeduren die von EnumChildWindows aufgerufen werden, // um auch die childs nacheinander zu subclassen bzw das subclassing zu entfernen bool childSubclassProc(HWND window,unsigned int lParam){ SetProp(window,"oldProc",(HANDLE)SetWindowLong(window,GWL_WNDPROC,(long) subclassProc)); SetProp(window,"messageTarget",(HANDLE)((InfoHolder*)lParam)->messageTarget); PostMessage((HWND)((InfoHolder*)lParam)->messageTarget,US_CHILD,(unsigned int)window,(unsigned int)((InfoHolder*)lParam)->parent); return true; } bool childRemoveSubclassProc(HWND window,unsigned int lParam){ long proc=(long)GetProp(window,"oldProc"); SetWindowLong(window,GWL_WNDPROC,proc); HWND messageTarget=(HWND)GetProp(window,"messageTarget"); RemoveProp(window,"oldProc"); RemoveProp(window,"messageTarget"); PostMessage(messageTarget,US_REMOVE,(unsigned int)window,0); return true; }
es ist ja normalerweise echt nicht meine art, soviel code zu posten, aber hier komm ich wirklich nicht weiter...
-
ich glaub, ich hab den fehler jetzt...im meinem hauptprogramm hatte ich ne konsole offen, und wenn ich über die beendet hab,dann ging das ganze den bach runter
//edit das wars doch noch nich ganz...
inzwischen wo ich nun keine konsole benutze, funktionierts in jedem programm-ausser explorer fenstern. Wenn ich zb den Arbeitsplatz öffne, und dann auf das fenster meines programms gehe, bekomme ich direkt vom explorer den fehler:
die Anweisung in "0xbf863473" verweist auf speicher in "0xbf863473". der vorgang read...
interessant ist, dass beide werte gleich sind, aber was ist an fenstern wie dem explorer so anders, dass sie beim subclassen kaputt gehen?