CreateProcess Explorer.exe -> topmost
-
Hi,
also ich habe eine Anwendung, die selbst topmost ist.
Nun kann per Ctrl+E ein neues Explorer-Fenster gestartet werden, was mit CreateProcess geschieht.Wie kann ich dieses Fenster topmost setzen ??

Habe schon mit EnumWindows, EnumThreadWindows, FindWindow usw. gekämpft, nur kriege ich es einfach nicht hin.
Ich weiß nicht, wie ich da vorgehen muss.Wer kann mir da helfen ??
Vielen Dank schon mal im Voraus.
-
Hi
Ich glaube kannst das mit der Funktion SetWindowPos() machen. Bin mir aber nicht mehr sicher. Sorry
Ansonnsten kannste ja mal bei MSDN schauen ob es geht.lowbyte
-
Das Problem ist es ja, dass man für SetWindowPos ein Handle auf das Fenster haben muss. Der Explorer ist als Prozess nur einmal zu finden, startet für jedes geöffnete Fenster aber einen neuen Thread.
Der Classname eines Explorerfensters ist "ExploreWClass", zumindest unter WinXP. Wenn also nur ein Fenster geöffnet wurde, so ist dies kein Problem, du rufst also EnumWindows mit deiner Funktion auf, diese vergleicht den Classname und ruft, falls dieser passt, bspw.SetWindowPos(hwndExp,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVEauf. Wenn mehrere Explorerfenster bestehen, dann kannst du evtl. auch zu Programmbeginn diese Handles in einer Liste speichern und vergleichen, sodass nur neu Erstellte in den Vordergrund rücken.
-
Du solltest lieber erklären, was Du vorhast...
Vielleicht findet sich eine andere Lösung, als die von Dir angestrebte...
-
Erstmal danke für die Antworten !

Ich habe eine Anwendung, in der man so einige Shortcuts nutzen kann, um z.B. den Taskmanager oder die cmd zu starten.
Und mit Ctrl+E kann man ein neues Explorer-Fenster starten (CreateProcess mit explorer.exe als Exe-File).Nur ist meine Applikation topmost und ich möchte, dass dieses gerade geöffnete Explorer-Fenster auch topmost wird bzw. eben über meiner erscheint.
Das ist mein Vorhaben.Wie viele Fenster es am Ende gibt, kann ich nicht voraussagen...
-
Es gibt kein Top-Mosterals Top-Most. Vielleicht solltest Dumal Dein Konzept überdenken, was Top-Most betrifft

-
Sorry Martin, aber ich versteh dich nicht ganz...

Davon abgesehen wüsste ich nicht, was ich sonst machen soll. Meine Applikation ist nun mal topmost.
-
Eben: Sie ist Top-Most und damit ist das Konzept in meinen Augen schon Mist

Etwas "topmoster" zu machen weil man schon "topmost" ist ist irgendwie abartig... Und wenn Du nun alle Programme aus Deiner Anwendung gestartet hast sind die alle topmost und Deine Software liegt wieder hinten. Wo ist nun der Sinn?Zwischen Anwendungen die Top-Most sind gibt es dennoch einen Z-Order. Auch die kannst Du mit SetWindowPosition bearbeiten. Hast Du das schon mal versucht.
-
Ja du hast nicht Unrecht !
Ich glaube, ist es vielmehr die Änderung der Z-Order, die ich eig. wollte.Nein habe es noch probiert, ich werde mal mit EnumWindows versuchen, das Handle zu diesem Explorer-Fenster zu bekommen.
Das war auch mein Problem.
-
Also so funktioniert es schon mal nicht:
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { char szClassName[MAX_PATH] = {0}; ::GetClassName(hwnd, szClassName, MAX_PATH-1); if (strcmp(szClassName, "ExploreWClass") == 0 || strcmp(szClassName, "CabinetWClass") == 0) { ::SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } return TRUE; }Das wäre ein Versuch von mir. Es ändert sich aber so keine Fensterposition. Das ist doch das, was du gemeint hast Martin, oder ?
-
Du kannst auch
if (strcmp(szClassName, "ExploreWClass") == 0 || strcmp(szClassName, "CabinetWClass") == 0) { SetForegroundWindow(hwnd); }verwenden.
-
Also, ich vergleiche, wie oben, den Class-Name, aber ich erreiche damit trotzdem nichts.
Mache ich da noch irgendwo etwas falsch oder ist es überhaupt möglich, das Explorerfenster so zu kontrollieren ??
-
Unter welcher Windows-Version arbeitest du? Der Klassenname, den ich gepostet habe, bezog sich auf WinXP.
Wenn du MS Visual Studio installiert hast, kannst du mit Spy++ (zu finden im Startmenu unter Tools) die Klassennamen von Fenstern auslesen.
Bei mir macht der Code keinerlei Probleme, wenn ich SetForegroundWindow aufrufe.
-
Unter Windows 7 mache ich das. Für XP habe ich gerade keine Testmöglichkeit.
Sorry, hab es echt vergessen zu erwähnen...
-

Hast du denn mal SetWindowPos(..) in deinem geposteten Code durch SetForegroundWindow ersetzt?
Du hast Recht, unter Win7 ist der Klassenname "CabinetWClass". Ich habe keine Probleme bei der Ausführung (unter Xp und 7).
-
Ja, ich habe SetWindowPos und SetForegroundWindow probiert, doch es wird das Explorerfenster bei mir einfach nicht in den Vordergrund gesetzt.
Meine Vorgehensweise:
GetWindowsDirectory(szExePath, sizeof(szExePath) / sizeof(TCHAR)); _tcscpy_s(szExeFile, MAX_PATH, szExePath); _tcscat_s(szExeFile, MAX_PATH, _T("\\explorer.exe")); ZEROINIT(procInf); ZEROINIT(si); si.cb = sizeof(si); si.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE | STARTF_USESHOWWINDOW; si.dwXSize = 800; si.dwYSize = 600; si.wShowWindow = SW_SHOW; if (CreateProcess(szExeFile, szExeCmd, NULL, NULL, TRUE, 0, NULL, szExePath, &si, &procInf)) { ::EnumWindows(&EnumWindowsProc, procInf.dwProcessId); CloseMyHandle(procInf.hProcess); CloseMyHandle(procInf.hThread); } ... BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { char szClassName[MAX_PATH] = {0}; ::GetClassName(hwnd, szClassName, MAX_PATH-1); if (strcmp(szClassName, "ExploreWClass") == 0 || strcmp(szClassName, "CabinetWClass") == 0) { SetForegroundWindow(hwnd); return FALSE; } return TRUE; }Damit funktioniert es nicht. Habe ich da noch irgendwas vermurkst ??
-
SetForegroundWindow setzt ein Fenster nicht TopMost und funtkioniert auch nur für Fenster des gleichen Prozesses. Siehe hier:
http://msdn.microsoft.com/en-us/library/ms633539(VS.85).aspxSetWindowPos ist schon korrekt, muss aber statt mit
::SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);mit
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);aufgerufen werden.
-
Das hatte ich ja auch schon geschrieben, klappt aber anscheinend nicht. Du könntest mal eine Kombination aus SetWindowPos mit HWND_TOPMOST und ForceForegroundWindow probieren.
HWND ForceForegroundWindow(HWND hTo) { if(!hTo) return(NULL); HWND hFrom=GetForegroundWindow(); if(!hFrom) { SetForegroundWindow(hTo); return(NULL); } if(hTo==hFrom) return(NULL); DWORD pid=GetWindowThreadProcessId(hFrom,0); if (_threadid==pid) { SetForegroundWindow(hTo); return(hFrom); } if(pid) { if(!AttachThreadInput(_threadid,pid,true)) return(NULL); SetForegroundWindow(hTo); AttachThreadInput(_threadid,pid,false); } return(hFrom); }
-
Also mit SetWindowPos funkioniert es, aber erst ab dem 2. Explorerfenster. Das 1. bleibt davon unberührt (unter XP und 7).
@Vicious Falcon: werde dein Source mal studieren und durchtesten und melde mich dann nochmal !
-
So, also ich weiß nicht, aber selbst das hilft mir nicht.
Er setzt ein Explorerfenster in den Vordergrund, wenn schon min. 1 offen ist.
Das 1. Explorerfenster kann er mir nicht in den Vordergrund setzen.Grundsätzlich funktioniert es schon, nur eben noch nicht mit dem allerersten Fenster.
Ich verstehe jetzt aber noch nicht ganz, wo da der Unterschied liegt:
- wenn schon min. 1 offen ist, setze ich 1 über das HWND topmost
- wenn noch keins offen ist, mache ich ja dasselbe, und dieser neue Prozess hat doch ebenso ein HWND zu seinem Fenster !!??Was fehlt da noch.... ??
EDIT: Ich habe noch eine Ergänzung: den Explorer kann man ja per /n dazu bringen, dass er jedes Fenster in einem neuen Prozess startet und diesen dann auch nicht killt.
Was sich unter XP und 7 auch schon wieder unterschiedlich verhält und SetWindowPos gleich reagiert.