Article View: be.comp.programming
Article #14380Re: c++,winNT: Hoe breng ik een willekeurige applicatie op de voorgrond?
From: Luc Kumps
Date: Tue, 13 Feb 2001 20:47
Date: Tue, 13 Feb 2001 20:47
117 lines
5215 bytes
5215 bytes
Eerst het slecte nieuws: volgens mij is dit probleem niet oplosbaar voor het
algemene geval.
Ten eerste kan een bepaalde .exe file meerdere keren in parallel uitgevoerd
worden. Je kan bijvoorbeeld drie iexplore.exe processen hebben: drie browser
windows. Welk process is dan "het" proces dat je zou willen op de voorgrond
brengen?
Ten tweede kan iedere applicatie vele windows hebben, zoals je zelf al
vastgesteld hebt. In Outlook kun je bv. verschillende messages openen. Dat
zijn allemaal windows die door outlook.exe behandeld worden. Welke is nu
"de" window die moet worden geactiveerd?
Dit gezegd zijnde, kan men natuurlijk proberen om een begin van een
oplossing te zoeken voor het probleem ;^)
Eerst en vooral, testen op parent==null is niet goed. Bijvoorbeeld, je start
de VC++ IDE, en je typt Ctrl-O. De "Open" dialog komt te voorschijn. De
parent van deze window is de "main" window, maar indien je "msdev" wenst te
activeren, dan is het de "Open" window die moet worden geactiveerd, en niet
de "main" window!
Waarop dan wel testen? Ik denk dat er drie "nuttige" attributen zijn:
1) Is er een title bar? (kan worden uitgezocht met GetWindowText)
2) Is de style WS_VISIBLE aanwezig (te bekomen met GetWindowInfo)
3) Is de style WS_DISABLED *niet* aanwezig? (het bovenstaand voorbeeld met
VC++ Ctrl-O zal de "main" window in disabled toestand zetten)
Ik heb eventjes geprobeerd om deze theorie in de praktijk om te zetten, en
dit geeft als resultaat:
if (dwProcessId==dwProcessIdToMatch) {
WINDOWINFO wi;
wi.cbSize = sizeof(wi);
if (!GetWindowInfo(hWnd, &wi)) return true;
if (wi.dwStyle & WS_DISABLED) return true;
if (!(wi.dwStyle & WS_VISIBLE)) return true;
char buffer[1000];
if (0==GetWindowText(hWnd, buffer, sizeof(buffer))) return true;
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
return false;
}
(ik heb SW_NORMAL vervangen door SW_RESTORE om te voorkomen dat een
maximized window in de "normal" grootte wordt getoond)
Dit allemaal zonder de garantie dat het in alle gevallen doet wat je wou, om
de hierboven aangehaalde redenen...
Waarschijnlijk zal de praktijk nog meer "nuttige" attributen geven...
Luc
"Colin Bouckaert" <colinb@covan.be> wrote in message
news:3a894669.27825180@news.skynet.be...
> Ik heb problemen bij het schrijven van c++ code (voor WinNT) om een
> willekeurige applicatie op de voorgrond te laten treden.
>
> Stel dat ik alleen de naam van het programma weet (b.v. explorer.exe,
> outlook.exe of gelijkwat.exe).
> Hoe breng ik deze applicatie dan op de voorgrond?
>
> Wat ik tot nu gedaan heb:
> eerst zoek ik het process id van de applicatie, gebruikmakende van
> EnumProcesses,OpenProcess,EnumProcessModules en
> GetModuleBaseName.
>
> Tenslotte gebruik ik EnumWindows om alle top level windows appart te
> onderzoeken op hun process id en de juiste naar de voorgrond te
> brengen (wat niet altijd lukt).
>
> EnumWindows(BringToForeground,LPARAM(dwProcessId);
>
> Deze functie roept mijn callback functie op voor iedere window totdat
> ze false return.
>
> // Globale callback functie
> BOOL CALLBACK BringToForeground( HWND hWnd, // handle parent window
> LPARAM lParam // ProcessId to match
> )
> {
> DWORD dwProcessIdToMatch = DWORD(lParam);
> DWORD dwProcessId=0;
>
> // Vraag het processId van het window
> GetWindowThreadProcessId(hWnd,&dwProcessId);
>
> // Komt het process id van het window overeen met deze
> // van de applicatie?
> if (dwProcessId==dwProcessIdToMatch
> && GetParent(hWnd)==NULL // Misschien onnodig
> )
> {
>
> // Gebruikmakend van VC++ heb ik gezien dat bepaalde applicaties
> // meerdere windows leveren waarvan het process id overeenkomt met het
> // process id van de applicatie (explorer.exe geeft er mij +/- 20.)
>
> // Hoe kan ik nu weten wanneer ik de juiste handle vast heb?????
> // Hoe kan ik dit testen????
>
>
> // Breng de application op de voorgrond
> ShowWindow(hWnd, SW_SHOWNORMAL);
> SetForegroundWindow(hWnd);
>
> // Stop de enumeratie
> return false;
> }
>
> // Ga door met de enumeratie
> return true;
> }
>
> Iemand enig idee?
>
> Colin
Technical Details
Message-ID:
<M3hi6.10000$Tu.447698@afrodite.telenet-ops.be>Path:
arc1-ca.pugleaf.net!supernews.google.com!sn-xit-02!supernews.com!isdnet!newsfeeds.belnet.be!news.belnet.be!afrodite.telenet-ops.be!not-for-mailReferences:
<3a894669.27825180@news.skynet.be>Show Full Headers
Complete Article Headers
X-Google-Language: DUTCH,ASCII-7-bit X-Google-Thread: fcea4,1c9fe68062fc1f1b X-Google-Attributes: gidfcea4,public X-Google-ArrivalTime: 2001-02-13 12:47:41 PST Path: arc1-ca.pugleaf.net!supernews.google.com!sn-xit-02!supernews.com!isdnet!newsfeeds.belnet.be!news.belnet.be!afrodite.telenet-ops.be!not-for-mail From: "Luc Kumps" <NOkumpsSPAM@pandora.be> Newsgroups: be.comp.programming References: <3a894669.27825180@news.skynet.be> Subject: Re: c++,winNT: Hoe breng ik een willekeurige applicatie op de voorgrond? Lines: 119 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Message-ID: <M3hi6.10000$Tu.447698@afrodite.telenet-ops.be> Date: Tue, 13 Feb 2001 20:47:40 GMT NNTP-Posting-Host: 213.224.221.59 X-Complaints-To: abuse@pandora.be X-Trace: afrodite.telenet-ops.be 982097260 213.224.221.59 (Tue, 13 Feb 2001 21:47:40 MET) NNTP-Posting-Date: Tue, 13 Feb 2001 21:47:40 MET Organization: Telenet Internet