C# - Hasznos API függvények implementációja C#-ban

forráskód letöltése
A .NET osztálykönyvtára számtalan metódust tartalmaz, mindent azonban nem lehet elvégezni velük. Sok feladat megoldása csak API függvényekkel lehetséges, hiszen ezek nem kerültek megvalósításra egyik osztályban sem. Cikkünkben megvizsgálhatjuk néhány hasznos metódus működését. Ezek a Beep, MessageBeep, az EnumDesktop, a GetSystemPowerStatus, a GetDiskFreeSpace és a GetShortPathName metódusok.
A Beep és a MessageBeep metódusokkal kapcsolatos feladatrészek kipróbálásához hangkártyával és hangfallal kell rendelkeznünk.
A cikkben bemutatjuk a bevezetőben említett metódusok deklarációit és használatukat. A példában a metódusok deklarációit a Win32 osztályban helyeztük el. A metódusok statikusak, így az osztály példányosítása nélkül meghívhatók.
Beep metódus
A metódus a kernel32.dll állományban található, és alkalmas arra, hogy hangokat szólaltassunk meg tetszőleges frekvenciával és hosszúságban. A deklarációja a következő:
[DllImport("kernel32.dll")]
public static extern bool Beep(int fr, int duration);
A metódus első paramétere a frekvencia értéke Hz-ben, egész számként megadva, míg a második paraméter a hang megszólaltatásának időtartama milliszekundumban.
Az alkalmazás Beep füle alatt ki kell választanunk egy frekvenciaértéket 100 és 1000 Hz között, és a hang 100 milliszekundum ideig fog szólni.
MessageBeep metódus
A MessageBeep metódus is hangok megszólaltatására alkalmas azzal a különbséggel, hogy a metódus paramétere a BeepType felsorolt típus egy eleme, mely egy előre definiált hang a Windows rendszerben.
A felsorolt típus elemei a következők:
public enum BeepType
{
  SimpleBeep = -1,
  IconAsterisk = 0x00000040,
  IconExclamation = 0x00000030,
  IconHand = 0x00000010,
  Ok = 0x00000000,
}
A metódust a következőképpen deklaráltuk:
[DllImport("user32.dll")]
public static extern bool MessageBeep(BeepType beepType);
Az alkalmazás MessageBeep füle alatt csak kiválasztunk egy elemet a listából, és a HANG feliratú nyomógombra kattintva megszólal az előre definiált hang.
Win32.MessageBeep(BeepType.SimpleBeep);
GetSystemPowerStatus metódus
A GetSystemPowerStatus metódus arra szolgál, hogy programból tudjuk lekérdezni laptop számítógépünk akkumulátorának jellemzőit, és ellenőrizni az állapotát.
A metódus meghívásakor egy SYSTEM_POWER_STATUS struktúrát kell átadnunk, mely a művelet végén tartalmazni fogja a fenti jellemzőket. Ennek menedzselt megfelelőjét készítettük el elsőként a Win32 osztályban.
public struct SystemPowerStatus
{
  public ACLineStatus ACLineStatus;
  public BatteryFlag batteryFlag;
  public byte batteryLifePercent;
  public byte reserved1;
  public int  batteryLifeTime;
  public int  batteryFullLifeTime;
}
A struktúra mezőinek jelentése a következő:
  • ACLineStatus: a mező típusa felsorolt típus, melynek három lehetséges értéke van, és amelyek az akkumulátor státuszát vannak hivatva jelezni, melyek ONLINE, OFFLINE és UNKNOWN lehetnek.
  • BatteryFlag: az akkumulátor töltöttségét kifejező felsorolt típus.
  • batteryLifePercent: az akkumulátor élettartamára vonatkozó százalékos érték, vagy ismeretlen érték esetén 255.
  • batteryLifeTime: másodpercekben jelzi az akkumulátor hátralévő élettartamát. Ismeretlen érték esetén -1.
  • batteryFullLifeTime: másodpercekben jelzi az akkumulátor élettartamát abban az esetben, amikor teljesen fel van töltve. Ismeretlen érték esetén -1.
A hívó alkalmazásban csak példányosítjuk a struktúrát, majd meghívjuk a metódust. Az eredményt a ListBox kontrolban láthatjuk.
SystemPowerStatus powerStatus = new SystemPowerStatus();
bool result = Win32.GetSystemPowerStatus(ref powerStatus);
listBox1.Items.Add(powerStatus.ACLineStatus);
...
Az eredmény természetesen csak laptop-on futtatott program esetén értékelhető, ott is csak abban az esetben, ha a gép az akkumulátorról üzemel.
GetDiskFreeSpace metódus
A függvény segítségével lekérdezhetjük a megadott betűjellel rendelkező meghajtó fájlrendszerére jellemző információkat. A metódus deklarációja a következő:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool GetDiskFreeSpace(
[MarshalAs(UnmanagedType.LPTStr)]
string rootPathName,
ref int sectorsPerCluster,
ref int bytesPerSector,
ref int numberOfFreeClusters,
ref int totalNumberOfClusters);
A függvény négy paramétert vár, melyek az eredményt tartalmazzák:
  • rootPathName: a meghajtó betűjele
  • sectorsPerCluster: a klaszterenkénti szektorok száma
  • bytesPerSector: a szektoronkénti bájtszám
  • numberOfFreeClusters: a szabad klaszterek száma
  • totalNumberOfClusters: az összes klaszter száma
A hívó alkalmazásban paraméterként megadjuk a meghajtó betűjelét (melyet a ComboBox kontrolból választunk) és megadunk négy változót, a kimeneti értékek tárolására. Az eredményt egy ListBox kontrolban helyezzük el.
GetShortPathName metódus
A metódusban a megadott létező és hosszú elérési útvonalakat rövidíthetjük le a szabványos 8x3-as méretre, hogy bizonyos alkalmazások számára se okozzon gondot a 32-bites Windows-ban megszokott hosszabb állomány- vagy mappanév.
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetShortPathName(
[MarshalAs(UnmanagedType.LPTStr)]
string path,
[MarshalAs(UnmanagedType.LPTStr)]
StringBuilder shortPath,
int shortPathLength);
A metódus első paramétere egy tetszőleges állománynév elérési útvonallal, míg a második egy StringBuilder objektum. A művelet végén ez az objektum tartalmazza a rövidített nevet, és ezt lekérdezhetjük egy szövegmezőben.
StringBuilder sp = new StringBuilder(textBox1.Text.Length);
Win32.GetShortPathName(textBox1.Text,sp,sp.Capacity);
textBox2.Text = sp.ToString();
EnumDesktops metódus
A metódus használatával láthatunk egy példát arra, hogy miként oldható fel az a korlátozás, hogy a függvények csak egy visszatérési értékkel rendelkezhetnek. Ennek feloldására használható a CALLBACK mechanizmus, melyben egy függvény címét adjuk át paraméterként a metódusnak.
A metódusban lekérdezhetjük egy adott ablakobjektum Asztalait. A metódus deklarációja a következő:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool EnumDesktops(IntPtr windowStation,EnumDesktopProc callback,int lParam);
Az első paraméter az ablakobjektum, melyet a GetProcessWindowStation metódussal kérdezhetünk le.
[DllImport("user32.dll")]
public static extern IntPtr GetProcessWindowStation();
A második metódus a CALLBACK címe, míg a harmadik paraméterben a callback metódusnak adhatunk át egy egyedi paramétert.
A CALLBACK metódus egy delegált, mely az Asztal-objektumok neveit gyűjti ki sorban.
public delegate bool EnumDesktopProc([MarshalAs(UnmanagedType.LPTStr)]string desktopName, int lParam);
A hívó alkalmazásban létrehoztunk egy callback deklarációt, hogy listába szedjük a neveket, és azokat egy ListBox kontrolban jelenítsük meg.
public bool DesktopCallback(string desktopName, int lParam)
{
  listBox3.Items.Add(desktopName);
  return true;
}
A metódus meghívása a következőképpen zajlik:
IntPtr w = Win32.GetProcessWindowStation();
Win32.EnumDesktops(w,new Win32.EnumDesktopProc(DesktopCallback), 0);