Použití Windows API v C# .NET - 3. díl
Pro velký zájem dávám k dispozici pár příkladů API z mé DB. Někdy chceme běžící aplikaci aktivovat, toto může být účelné poté, co jsme zabránili jejímu vícenásobnému spuštění. Zde můžeme použít metodu AppActivate z modulu Interaction ze jmeného prostoru Microsoft.VisualBasic. Tato metoda má ovšem nedostatek, neumí minimalizovanou aplikaci po aktivaci obnovit do původního režimu. Řešením tohoto problému jsou metody:
- ActivateApplicationByProcess(Process process) umožňuje aplikaci obnovit do původního stavu.
- ActivateApplicationByPartialTitle(...) - Mnohé aplikace vypisují v titulku okna kromě názvu také další informace, není je možné aktivovat dle úplného titulku. Tato funkce zpracuje i část titulku.
- GetWindowClassName() hledá okno ze zadaným titulkem (může se použít jako pomocná metoda)
Popis deklarovaných API
Abychom mohli metody implementovat, musíme nejdříve deklarovat tyto Windows API:
Vyhledá okno nejvyšší úrovně s daným názvem třídy a názvem okna. Dceřiná okna se neprohledávají.
[DllImport("user32", SetLastError = true)] protected static extern int FindWindow(string lpClassName, string lpWindowName);
Používá se ke zjištění délky titulku okna nebo textu ovládacího prvku před voláním GetWindowsText(). Funkce zřizuje vyrovnávací paměť, která je dostatečně velká pro vyhledaný text.
[DllImport("user32", SetLastError = true)] protected static extern int GetWindowTextLength(IntPtr hWnd);
Načítá titulek mateřských překrývaných a dceřiných oken, nebo texe z ovládacího prvku.
[DllImport("user32", SetLastError = true)] protected static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
Vynáší vlákno, které dané okno vytvořilo na popředí a aktivuje okno, přičemž mu dává zvýraznění pro vstup.
[DllImport("user32", SetLastError = true)] protected static extern int SetForegroundWindow(IntPtr hwnd);
Kontroluje, zda je okno v daném okamžiku zobrazeno v minimalizovaném stavu. To znamená, že aplikace je v daném okamžiku zobrazena pouze ikonou.
[DllImport("user32", SetLastError = true)] protected static extern int IsIconic(IntPtr hwnd);
Obnovuje minimalizované okno do jeho původní velikosti a pozice, pak okno také aktivuje.
[DllImport("user32", SetLastError = true)] protected static extern int OpenIcon(IntPtr hwnd);
Navrací název třídy, se kterou bylo dané okno vytvořeno.
[DllImport("user32", SetLastError = true)] protected static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName,int nMaxCount);
Nastavuje stav zobrazení okna. Určuje, jak je okno zobrazeno na obrazovce.
[DllImport("user32", SetLastError = true)] protected static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
Fukce ActivateApplicationByProcess(Process process)
/// <summary> /// Aktivuje aplikaci pomocí objektu typu Process /// Pokud máme pro aplikaci object typu Process , popřípadě, když voláme metodu IsOtherInstanceRunning , /// můžeme tuto aplikaci dostat do popředí. /// </summary> /// <param name="process">Odkaz na objekt typu Process</param> /// <exception cref="Exception"> /// Vyvolá výjimku, když při obnově okna dojde k chybě, /// nebo když proces nemá žádné hlavní okno. /// </exception> public static void ActivateApplicationByProcess(Process process) { if ((int)process.MainWindowHandle != 0) //Získá popisovač okna hlavního okna přidruženého procesu { if (IsIconic((IntPtr)process.MainWindowHandle) != 0) //je okno minimalisované ?? { // Přenesení hlavního okna do popředí if (OpenIcon(process.MainWindowHandle) == 0) //dá se obnovit? { throw new Exception("Chyba Windows " + Marshal.GetLastWin32Error() + " při obnovování " + "okna procesu " + process.ProcessName + "' z minimalizovaného stavu."); } } // Přenesení okna do popředí if (SetForegroundWindow(process.MainWindowHandle) == 0) { throw new Exception("Chyba Windows " + Marshal.GetLastWin32Error() + " při přenosu hlavního " + "okna procesu '" + process.ProcessName + "' do popředí"); } } else { throw new Exception("Proces '" + process.ProcessName + " nemá hlavní okno."); } }
Funkce ActivateApplicationByPartialTitle(...)
public static void ActivateApplicationByPartialTitle(string mainWindowTitle, bool activaceDeactivace) { string errors = null; const int SW_MINIMIZE = 6; // Projdeme všechny procesy foreach (Process process in Process.GetProcesses()) { //Popisovač pouze pro okna v lokálním PC. Hlavní okno je vždy první okno bez ohledu zda má aplikace //více oken. Získá popisovač okna hlavního okna přidruženého procesu if ((int)process.MainWindowHandle != 0) { // Zjistíme délku textu hlavního okna int windowTextLength = GetWindowTextLength(process.MainWindowHandle); // Zjistíme text hlavního okna StringBuilder windowTextBuilder = new StringBuilder(windowTextLength + 1); if (GetWindowText(process.MainWindowHandle, windowTextBuilder, windowTextLength + 1) > 0) { // Zjistíme, zda se předaný text vyskytuje v textu aktuálního okna string windowText = windowTextBuilder.ToString(); string windowTextOpr = Left(windowText, mainWindowTitle.Length); //pokud se nerovná hodnotě -1 je tento řetězec nalezen if ((windowText.IndexOf(mainWindowTitle) > -1) & (windowTextOpr == mainWindowTitle)) { try { // Hledání okna s předaným titulkem a jménem třídy // Handle nalezené třídy windowHandle = FindWindow(null, windowText); if (activaceDeactivace) DeactivaceTitle(windowHandle, windowText); else ShowWindow((IntPtr)windowHandle, SW_MINIMIZE); return; } catch (Exception ex) { if (errors != null) { errors += Environment.NewLine; } errors += ex.Message; } }//if windowText }//GetWindowText }//(int)process }//foreach // Vyhodnocení chyb skok na globální odchyt modul Program.cs if (errors != null) { throw new Exception(errors); } { // Okno ze zadaným titulkem nebylo nalezeno throw new Exception("Okno s titulkem '" + mainWindowTitle + "' nebylo nalezeno"); } }//ActivateApplicationByPartialTitle
Funkce GetWindowClassName(....)
public static string GetWindowClassName(string windowTitle) { int windowHandle = FindWindow(null, windowTitle); if (windowHandle != 0) { StringBuilder className = new StringBuilder(255); if (GetClassName((IntPtr)windowHandle, className, 255) > 0) { return className.ToString(); } else { throw new Exception("Chyba Windows " + Marshal.GetLastWin32Error() + " při zjišťování " + " jména třídy okna s titulkem '" + windowTitle + "'"); } } else { throw new Exception("Okno s titulkem '" + windowTitle + "' nebylo nalezeno"); } }
Zdrojové kódy přiloženy.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 83x (23.53 kB)
Aplikace je včetně zdrojových kódů v jazyce C#