Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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.Visu­alBasic. 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:

  • ActivateAppli­cationByProces­s(Process process) umožňuje aplikaci obnovit do původního stavu.
  • ActivateAppli­cationByParti­alTitle(...) - 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.
  • GetWindowClas­sName() 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 ActivateAppli­cationByProces­s(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 ActivateAppli­cationByParti­alTitle(...)

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 GetWindowClas­sName(....)

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 82x (23.53 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Všechny články v sekci
Programování služeb ve Windows
Článek pro vás napsal zpavlu
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
C# , C++ a assembler
Aktivity