Verständnisfrage zu top-level Windows



  • Hallo Forum,
    ich habe eine Applikation die dafür sorgt verschiedene Programme zu starten bzw. zu schlissen. Um die Programme zu schlissen wird aus eine Konfig Datei ein KlassenName gelesen und über die Fkt. FindWindow ein Handle auf Window geholt. Dann wird ein WM_CLOSE an das Window gesendet.
    Diese bestimmung der Klasse würde ich jedoch automatisiert haben wollen. Dazu verwede ertsmal ich die Fkt EnumWindows und GetWindowThreadProcID um überhaupt es verstehen zu können was da passiert. Was ich jedoch nicht ganz verstanden habe sind die gefundenen HWNDs mit gleichen ProcID (auf mein zu schliessenden Applikation).

    Meine Fragen:
    1. Warum sehe ich so viele Hwnds meine zu schlissender App?
    2. Welche wäre der richtige HWND an dem ich die WM_CLOSE schicken muss?



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hi,

    WM_CLOSE reicht nicht, viele hidden nur das Fenster, WM_DESTROY ist angezeigt,
    dies dürfte dann zu abstürzen führen, weil deren MainApp nicht mehr klar kommt.

    BEsser ist es über den Prozesszugriff ´den ganzen Prozess zu terminieren.
    Etwas fummelig wird es ein Fenster einem Prozess zuordnen zu können. Daher besser wenn Du den Prozess namen in deine Config einträgst.

    Beispiel auflistung laufender Prozesse:

    Pseudo Beispiel:

    #include <tlhelp32.h>
    
    DWORD FindProcess(char *pName,int prcnt/*=0*/)
    {
    	typedef HANDLE (WINAPI *PFN_CREATETHELP32SNPSHT)(DWORD,DWORD);
    	typedef BOOL   (WINAPI *PFN_PROCESS32FIRST)(HANDLE,PROCESSENTRY32*);
    	typedef BOOL   (WINAPI *PFN_PROCESS32NEXT)(HANDLE,PROCESSENTRY32*);
    
    	PFN_CREATETHELP32SNPSHT fnCreateToolhelp32Snapshot;
    	PFN_PROCESS32NEXT fnProcess32Next;
    	PFN_PROCESS32FIRST fnProcess32First;
    
    	HMODULE hWin95Kernel = GetModuleHandle("kernel32.dll");
    	if(!hWin95Kernel) 
    	  return 0;
    
    	if(!(fnCreateToolhelp32Snapshot=(PFN_CREATETHELP32SNPSHT)GetProcAddress(hWin95Kernel,"CreateToolhelp32Snapshot")) )
    	  return 0;
    	if(!(fnProcess32First=(PFN_PROCESS32FIRST)GetProcAddress(hWin95Kernel,"Process32First")) )
    	  return 0;
    	if(!(fnProcess32Next=(PFN_PROCESS32NEXT)GetProcAddress(hWin95Kernel,"Process32Next")) )
    	  return 0;
    
    	PROCESSENTRY32 process;process.dwSize=sizeof(PROCESSENTRY32);
    	HANDLE handle = fnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    	if(!handle) return 0;
    
    	int n=0;fnProcess32First(handle,&process);
    	do
    	{
    	 if(!strncmp(process.szExeFile,pName,strlen(pName)))
    	  if(n++ >= prcnt) return process.th32ProcessID;
    	}while(fnProcess32Next(handle,&process));
    
    	return 0;
    }
    

    Gruß K.



  • Ja, das mache ich schon nur das terminieren ist ja auch keine gute Lösung da man der App keine Chance gibt sich ordnungsgemäss zu beenden was beim Schreiben von Files zu korrupten Dateien kommen kann.
    Also war meine Idee die mit WM_CLOSE versuchen zu schlissen, etwas abzuwarten und wenn die App noch da sein sollte dann zu terminieren.
    Das einziger was mir fehlt ist es automatisch den Klassennamen bzw. Windownamen zu bestimmen.



  • Versuche doch mal WM_QUIT an eines der Fenster zu senden, bzw PostQuitMessage zu verwenden.



  • Oder WM_ENDSESSION ..


  • Mod

    Weder WM_DESTRY noch WM_ENDSESSION darf man an ein anderes Fenster senden. Es sind nur Notifications, die ausschließlich von Windows ausgelöst werden.
    Genauso wie WM_QUIT.
    Das sind alles "illegale" Holzhämmer...

    WM_CLOSE wäre richtig, aber viele Anwendungen Fragen ja dann ja noch ob Änderungen gespeichert werden sollen.

    Was Du siehst sind alles nicht sichtbare Fenster für COM, Tooltips etc...
    Aber von Deiner gesuchten Klasse dürfte es nur eines geben. Schau Dir das mal mit Spy++ an.



  • Aber ganau das ist mein Problem wenn ich die Klasse bzw. Window automaisch bestimmen möchte. Durch das EnumWindow erhalte ich z.B.

    Trace Auszug aus EnumWindow

    ...
    Class WindowsForms10.Window.0.app.0.141b42a_r14_ad1 ProcID 5020
    Class GDI+ Hook Window Class ProcID 5020
    Class .NET-BroadcastEventWindow.4.0.0.0.141b42a.0 ProcID 5020
    ...

    Was sind meine Entscheidungskriterien die richtige Klasse zu nehmen und den WM_CLOSE zu schicken?


  • Mod

    Das es zum Beispiel sichtbar ist und eine Ausdehnung hat.

    Ansonsten musst Du selber die Klasse bestimmen, damit Du das richtige triffst.
    Spy++ kann helfen... (ich wiederhole mich)


Anmelden zum Antworten