C# - Alkalmazás ikonjának lekérdezése

forráskód letöltése
A .NET osztályainak segítségével számtalan információt lekérdezhetünk a fájlrendszer egy adott eleméről, azonban a fájlhoz rendelt alkalmazás ikonját nem tudjuk lekérdezni. Ehhez igénybe kell vennünk egy Windows API függvényt, melyet a Shell32.dll állományban találunk meg. A mellékelt példában bemutatjuk, hogy milyen paraméterekkel kell meghívnunk az adott függvényt, és a kapott értéket hogyan nyerhetjük ki.
A mellékelt projektben megnyithatunk egy tetszőleges állományt a MEGNYITÁS gombbal, miután az állományhoz rendelt alkalmazás ikonja megjelenik a Form sárga hátterű paneljén. A Form-ra helyezett ComboBox kontrolban kiválaszthatjuk, hogy az adott alkalmazás kis méretű (16x16 pixeles), vagy nagy méretű (32x32 pixeles) ikonját kívánjuk megjeleníteni.
Az ikon lekérdezését a projekt Win32 nevű osztályába ágyaztuk. A Shell32.dll SHGetFileInfo metódusával történik meg a lekérdezés, melyet deklarálnunk kellett.
[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SH_FILE_INFO psfi, uint cbSizeFileInfo, uint uFlags);
A metódus első paraméterében kell megadnunk a lekérdezendő fájl elérési útvonalát egy karakterláncban. Opcionálisan a második paraméterben megadhatunk a fájl attribútumaira vonatkozó információt, ez most nulla értékű lesz.
A harmadik paraméter tartalmaz egy referenciát a fájl információit tartalmazó struktúrára. A negyedik paraméter a struktúra méretét tartalmazza, míg az ötödik paraméterben egy konstans értéket kell megadnunk, melynek értéke függ a lekérdezendő információtól.
A megadandó struktúra deklarációja a következő:
[StructLayout(LayoutKind.Sequential)]
public struct SH_FILE_INFO
{
  public IntPtr hIcon;
  public IntPtr iIcon;
  public uint dwAttributes;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  public string szDisplayName;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
  public string szTypeName;
}
A struktúra hIcon mezője fogja tartalmazni a lekérdezendő ikonra mutató pointert. Annak érdekében, hogy a lekérdezés az ikonra vonatkozzon, a megfelelő értéket kell megadnunk az utolsó paraméterben.
Ehhez deklaráljuk a konstansokat.
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0;
public const uint SHGFI_SMALLICON = 0x1;
A kis ikonok lekérdezéséhez a SHGFI_ICON és a SHGFI_SMALLICON konstansok kombinációját kell megadnunk, míg a nagy méretű ikonokat a SHGFI_ICON és a SHGFI_LARGEICON konstansok kombinációjának megadása szükséges.
A GetFileIcon metódusban pedig meghívjuk az API függvényünket a paraméterként kapott elérési útvonalat felhasználva. Első lépésként példányosítjuk a struktúrát.
SH_FILE_INFO fileinfo = new SH_FILE_INFO();
Majd a kis ikonok lekérdezéséhez a következőképpen hívjuk meg a metódust:
SHGetFileInfo(filename,0,ref fileinfo,(uint)Marshal.SizeOf(fileinfo),SHGFI_ICON|SHGFI_SMALLICON);
Az első mezőben kapott kezelőből létrehozunk egy Icon objektumot, melyet a metódus visszaad.
Icon fileicon = Icon.FromHandle(fileinfo.hIcon);
Az ikont egy globális objektumban helyezzük el, melyet megjelenítünk a Panel kontrol felületén.
fileicon = Win32.GetFileIcon(textBox1.Text,comboBox1.SelectedIndex);
Ehhez frissítjük a Form kliensterületét, amikor is meghívódik a Panel objektum OnPaint metódusa, melyben elhelyezzük saját kódunkat. Ekkor specifikáljuk, hogy az Icon objektum kirajzolása csak akkor történjen meg, ha a fileicon objektum nem NULL értékű, vagyis már lekérdeztük az adott alkalmazás ikonját.
g.DrawIcon(fileicon,(panel1.Width - fileicon.Width)/2,(panel1.Height - fileicon.Height)/2);
A kirajzoláshoz a Graphics osztály DrawIcon metódusát használjuk. Az alkalmazás ikonját már felhasználhatjuk arra, hogy annak futásakor megjelenítsük azt a Tálcán.