Použití Windows API v C# .NET - 3. díl

C# .NET Pro pokročilé 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ženo 58x (23.53 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal zpavlu
Avatar
C# a C++

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Všechny články v sekci
C# - Pro pokročilé

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!