TP

.Net - Používání Windows API funkcí

Co tento článek ukazuje

Windows API

Operační systém Windows umožňuje aplikacím, které pod ním běží přistupovat k OS pomocí takzavaných API funkcí. Pokud píšete aplikaci pro Windows, která nepoužívá žádné další knihovny, budete muset přímo volat tyto API funkce. V knihovně .Net je zaobaleno velké množství funkcí, takže se vám málokdy stane, že potřebujete dělat něco na co není v .Netu funkce, přesto ale může být někdy potřeba volat funkci, kterou v .Net Frameworku nenaleznete. .Net naštěstí umožňuje importování API funkcí a jejich volání pomocí takzvaného platform invoke.

Ukázková aplikace

Ukázkové aplikace bude pomocí API funkce GetForegroundWindow zjišťovat jaké okno je aktivní a pomocí funkce GetWindowText. zjistí titulek tohoto okna. Aplikace bude titulek zjišťovat na pozadí pomocí objektu Timer (který umožňuje vyvolávat událost jednou za daný časový interval). Dále bude aplikace umět minimalizovat hlavní okno jiné aplikace (té aktivní) a to pomocí funkce ShowWindow. Toto se bude dělat také pomocí objektu Timer, protože při kliknutí na tlačítko je vždycky aktivní naše aplikace. Bude tedy možné kliknout na tlačítko a aplikace po pěti sekundách minimalizuje aktivní okno. Pokud si chcete s okny zkusit i další operace, podívejte se na funkce pro práci s okny.

Ukázková aplikace

Deklarace API funkcí

Pokud chcete používat API funkce ve vašem programu, musíte nejprve každou funkci nadeklarovat a říct .Net Frameworku jaké má parametry a v jaké se nalézá knihovně. Pokud se podíváte například na funkci ShowWindow, zjistíte že se nalézá v knihovně user32.dll a že její parametry jsou HWND a int. HWND se do .Netu překládá jako IntPtr, takže deklarace funkce v C# bude vypadat následovně (deklarace funkcí musí být vloženy v nějaké třídě jako statické metody):

// Toto je potreba kvuli atributu DllImport
using System.Runtime.InteropServices;
  
// Import funkce ShowWindow z knihovny user32.dll
[DllImport("user32.dll")]
static extern IntPtr ShowWindow(IntPtr hWnd,int nShow);

Tyto deklarace lze také nalézt na internetu (viz [2]). Další funkce, se kterou chceme pracovat je GetWindowText. Import této funkce je trošku obtížnější, protože práce s textovými řetězci v .Netu a WinAPI se liší. Naštěstí .Net obsahuje třídu StringBuilder, kterou je možné předat funkci místo parametru typu LPSTR. Pomocí atributu [Out] ještě dáváme najevo, že parametr je výstupní (ale přesto je nutné objekt inicializovat). Deklarace funkce GetWindowText tedy vypadá takto:

// Import funkce pracujici s textovym retezcem
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd,
  [Out]StringBuilder lpString,int nMaxCount);

Volání API funkcí

Pokud máte nadeklarované funkce, můžete s nimi pracovat jako s normálními statickými funkcemi. Je však třeba dávat pozor na některé detaily při volání, které jsou způsobeny tím, že API funkce fungují jinak. Například u funkcí pro práci s textem musíte napřed vytvořit objekt StringBuilder s nějakou kapacitou (do kterého funkce může zkopírovat text) a tuto kapacitu předáte jako další parametr. Kód z ukázkové aplikace, který zjišťuje titulek aktivního okna vypadá takto:

// Zjistit identifikator (handle) aktivniho okna
IntPtr handle=GetForegroundWindow();

// Vytvorit StringBuilder s kapacitou 256 znaku
StringBuilder sb=new StringBuilder(256);
GetWindowText(handle,sb,sb.Capacity);

// Zobrazit titulek MessageBoxem
MessageBox.Show(sb.ToString());

Pokud použijete špatnou deklaraci funkce, nebo se pokusíte importovat funkci, která neexistuje vyhodí .Net vyjímku až při prvním volání funkce. Vyjímka DllNotFoundException znamená, že jste zadali špatné jméno DLL knihovny s funkcí a vyjímka EntryPointNotFoundException znamená, že se v dané knihovně nenachází požadovaná funkce (máte tedy buď špatně jméno funkce a nebo hledáte funkci v jiné knihovně).

Soubory na stažení a odkazy

Published: Monday, 25 April 2005, 1:11 AM
Author: Tomas Petricek
Typos: Send me a pull request!
Tags: