A Win32 API lehetőséget nyújt az alkalmazások számára bizonyos speciális, bináris jellegű információk csatolására és tárolására a futtatható állományokban. Az ún. erőforrások (resources) a program kódjától és adatterületitől elkülönített módon kerülnek tárolásra, és azok betöltődésekor nem kerülnek automatikusan a memóriába, hanem e helyett az alkalmazásnak explicit Win32 API hívásokkal kell az operációs rendszert megkérnie azok betöltésére.

Az erőforrások jellemzői

 Az erőforrások alapvetően csak-olvasható adatterületként kezelendők. Bár módosításukra programmatikus módon is lehetőség van, így elméletileg viszonylag gyakran változó adatok - pl. konfiguráció - tárolására is lehetőséget nyújtanának, valójában nem ebben rejlik igazi gyakorlati hasznuk. Az erőforrások úgy adnak lehetőséget nagy méretű adatterületek a fájlrendszer szintjén a program futtatható kódjával együtt történő kezelésére, hogy közben nem befolyásolják negatívan az alkalmazás memóriafoglalását. Sőt, bizonyos esetekben jelentősen csökkenthetik azt, mert az erőforrások - referencia-számolt objektumok lévén - fizikailag mindig csakis egyetlen példányban vannak jelen az operatív memóriában akkor is, ha az alkalmazás több helyen használja fel őket. Ráadásul mivel csak olvasható adatterületekról van szó, amelyek tartalmát a futtatható állományból az eredeti alapján bármikor reprodukálni lehet, így az operációs rendszer a memória-erőforrások szűkössé válása esetén automatikusan felszabadíthatja a velük társított fizikai memóriaterületet a nélkül, hogy annak tartalmát előtte - mint más memóriaterületek esetében - a lapozófájlba kellene mentenie. Amikor aztán az alkalmazásnak újból szüksége van az erőforrásban tárolt adatokra, az operációs rendszer - az alkalmazás számára teljesen transzparens módon - a futtatható állományból ismét a memóriába töltheti azok tartalmát.

Az erőforrások egy másik fontos jellemzője, hogy az alkalmazás kódjától és egyéb adatterületeitől gondosan elválasztva, standardizált formátumban kerülnek tárolásra, ami lehetővé teszi manipulálásukat külső eszközök segítségével a program kódjának és belső adatszerkezeteinek legcsekélyebb módosítása és működése ismerete nélkül is. Ez a gyakorlatban azt jelenti, hogy egy megfelelően kialakított program bizonyos adatterületei a forráskód hiányában, a program újrafordítása nélkül is szabadon módosíthatóvá válnak. Ez utóbbi lehetőségnek elsősorban a lokalizáció, azaz egy program helyi (nemzeti) verzióinak elkészítésekor van jelentősége, hiszen ez a feladat a program forráskódjával nem rendelkező egyének vagy csapatok számára is lehetővé teszi a nemzeti változatok elkészítését.

Az erőforrásokhoz hasonló jellegű entitásokat nem támogató architektúrákban az adatokat általában a kóddal vegyítve, vagy jobb esetben külön adatszegmensben tárolták. (Természetesen ezen rendszerek esetében is lehetőség volt az erőforrásokhoz hasonló mechanizmusok megvalósítására saját fájlformátumok és könyvtárak használatával, de ezen megoldások elérhetősége mások számára nyilvánvalóan erősen korlátozva volt.) Ezekben az - immár elavultnak tekinthető - rendszerekben a lokalizáció során nem volt más lehetősége a fordító csapatnak mint, hogy a felhasználói interfészen megjelenő üzeneteket a program kódjában megkeresse, és azokat a saját nyelvére lefordítsa. Mivel azonban ezen adatok belső tárolási formátuma általában nem volt ismert, vagy ha mégis, akkor sem volt lehetőség a - kód és adat "összedrótózásának" köszönhetően - az adatterületek az igényeknek megfelelően történő szabad átméretezésére. Ezekből az időkből származnak a ma már mindenki által jól ismert "Help"Ž "Súgó", "Exit" Ž "Vége" , "Options" Ž "Opciók", stb. kényszerfordítások, ahol jobb esetben az eredeti szövegnél nem-hosszabb, rosszabb esetben mindenképp' egyenlő hosszúságú szavakra voltak kénytelenek az eredeti kifejezéseket lecserélni, ami - figyelembe véve pl. a magyar és az angol nyelv átlagos szóhosszában és kifejezései gazdagságában mutatkozó eltéréseket - sokszor igen nagy találékonyságot, bő szókincset és fejlett asszociatív készséget igényelt a fordítást végző személyektől.
Természetesen a lokalizáció nem csak szöveges információk (mondatok, kifejezések) nyelvi fordítását takarja, hiszen a programban alkalmazott betűkészletek vagy képek is tartalmazhatnak egyedi, a lokalizációval összefüggésbe hozható információkat (gondoljunk csak a kínai vagy az arab írásjelekre, a nemzeti karakterekre). Ráadásul az is elképzelhető, hogy a lokalizáció során - a nyelv specialitásaiból adódóan - bizonyos dialógusok vagy akár egész képernyők módosítására vagy akár teljes átszervezésére is szükség lehet (pl. arab nyelvterületen a számunkra természetes balra rendezés helyett a szöveg és grafikus elemek jobbra igazítása a jellemző). A hagyományos architektúrák esetén - ahol nem voltak még Windows stílusú erőforrások - egy ilyen átalakítás gyakorlatilag elképzelhetetlen volt a teljes program újrafordítása nélkül. Szerencsére Win32 alatt a hasonló átalakítások már nem jelentenek technikai problémát.

Természetesen az alkalmazásnak magának a Win32 architektúrában is felkészültnek kell lennie -e módosításokra - de csakis addig a fokig, hogy a lokalizáció során módosítandó adatait az adatszegmens helyett erőforrásokban kell tárolnia. Ez a modern fordítókban általában csak az adott adat deklarálásához használt kulcsszó lecserélését igényli (pl. Delphi esetén a sztring-konstansok deklarálásához a hagyományos "const" kulcsszó helyett a "resourcestring" szót kell alkalmazni) amelyet észlelve a fordító automatikusan erőforrásként tárolja majd az adott változót és a program kódját is ennek megfelelően generálja. De kevésbé fejlett eszközök esetén sem igényelt különösebben nagyobb erőfeszítéseket a program készítője részéről - a plussz fáradtság gyakorlatilag már egyetlen fordítás esetén megtérült, és összességében kevesebb időt igényelt, mint hagyományos megoldások alkalmazása esetén.

Erőforrás-azonosítók

A hagyományos WinAPI-ban a futtatható álományon belül minden egyes erőforrást típusa (lásd később), és a típusán belüli egyedi azonosítója azonosít. Mind az erőforrás típusa (resource type), mind egyedi azonosítója (resource identifier) egy 0-65535 közötti egész szám, vagy egy tetszőleges hosszúságú karakterfüzér lehet. A számmal azonosított erőforrások adminisztrációs területei nyilvánvalóan kevesebb területet foglalnak el, és az operációs rendszer gyorsabban találja meg őket, mint karakterlánccal azonosított társaikat - bár ezen jellemzőkben mutatkozó különbségek a mai rendszereken már igazából nem észrevehetőek.

A névvel és a számmal azonosított erőforrások ugyanazokkal az API függvényekkel manipulálhatók, amelyek mindegyike az erőforrás típusaként és neveként is egy zérus-terminált karaktersorozatra (PChar) mutató pointert vár paraméterként. Amennyiben a paraméterként kapott pointer felső 16 bitje mind 0-t tartalmaz, azaz a pointer 64K alatti virtuális címterületre mutatna (ami Win32 alatt érvénytelen címtartomány), úgy annak értékét az API függvény egész számként értelmezi, és az adott számú erőforrásra történő hivatkozásként értelmezi. Amennyiben pedig a kapott pointer felső 16-bitjei közül legalább egy darab 0-tól eltérő értékét tartalmaz úgy igazi, karakterfüzérre mutató pointerként értelmezi, és a megadott virtuális címtől kezdődően tárolt (zérus-terminált) karakterfüzérrel azonosított erőforrásra történő hivatkozásként értelmezi azt.

A Win32 API a WinAPI-val felülről teljesen kompatíbilis módon működik (tehát a fent leírtak utóbbi esetében is mind, kivétel nélkül igazak), de egy fontos bővítést vezet be: az ún. nyelvi azonosítók (language identifiers) használatát az erőforrások elérésében. A nyelvi azonosítók egy plussz szintet jelentenek az erőforrások megkülönböztetésében: az erőforrás típusa és a típuson belüli azonosítója mellett a nyelvi azonosító az a harmadik jellemző, ami egyértelműen azonosít egy erőforrást a futtatható állományon belül. Ez a megoldás lehetőséget nyújt az alkalmazások számára akár több különböző nyelvterülethez tartozó információk párhuzamos, strukturált tárolására és egyszerű elérésére egyetlen futtatható állományon belül is.

Amikor egy alkalmazás az erőforrás elérésekor nem jelöl meg nyelvi azonosítót, abban az esetben a Windows automatikusan a rendszerben éppen aktuális területi beállításoknak megfelelő változatot próbálja meg betölteni a megjelölt erőforrás különböző nyelvi változatai közül. Amennyiben ilyen nyelvű változat nem lelhető fel a futtatható állományban, úgy természetesen az alapértelmezett (a futtatható állományban alapértelmezettként megjelölt) nyelvű változattal fog dolgozni.
Természetesen az alkalmazásnak módjában áll explicit megadni a betölteni kívánt erőforrás nyelvi azonosítóját is, így akár az aktuális nyelvi beállításoktól függetlenül is válthat nyelvet, vagy egyéb célokra használhatja fel a különböző nyelvi változatait ugyanannak az erőforrásnak.

Az erőforrások típusai

Az erőforrások alapvetően két nagy csoportra oszthatók annak függvényében, hogy milyen jellegű adatot tárolnak: a standard és az alkalmazás által definiált típusúakra.  A standard típusú erőforrások ikonok, kurzorok, képek, metafájlok, menük, dialógusok, betűkészletek, üzenet- és sztringtáblázatok valamint ún. gyorsító-táblák és verzió-információk tárolására alkalmasak, míg az alkalmazás által definiált egyedi erőforrások tetszőleges egyéb - vagy akár hasonló jellegű, de nem standard formátumban tárolt - az alkalmazás által igényelt adatot tárolhatnak.
Fontos különbség a két típus között, hogy míg a standard erőforrások esetében nem csak a tartalmazott adat jellege határozható meg pontosan, de az adott típusú információ maga is szabványos - természetesen típusonként eltérő - formátumban kerül tárolásra, addig a nem-standard azonosítók esetében nincs szabványos mód a tartalmazott információk szerkezetének leírására (azaz metaadatok tárolására), tehát ezen adatok manipulálása csakis az alkalmazott fizikai adatformátum pontos ismeretében lehetséges. Ennek megfelelően a standard típusuk és formátumok alkalmazása esetén a Win32 API olyan rutinokat bocsát az alkalmazások rendelkezésére, amelyek segítéségével az erőforrásokban tárolt standard formátumú ikonok, képek, betűtípusok, stb. közvetlenül betölthetők - akárcsak egy fájlból. Ezzel szemben az alkalmazás által definiált típusok esetén azok tartalma gyakorlatilag csak statikus adatfolyamként érhető el, amelynek esetleges átalakításáról és manipulálásáról az alkalmazásnak magának kell gondoskodnia. (Pl. JPEG képek minden további nélkül tárolhatók erőforrásként, de mivel a JPEG állományokhoz nincs standard Windows erőforrás-típus társítva, így az alkalmazásnak magának kell gondoskodnia a JPEG állomány beolvasásáról és bittérképpé történő konvertálásáról ha annak tartalmát a GDI segítségével meg szeretné jeleníteni.)

Az alábbi táblázat a standard erőforrás-típusokat tartalmazza:
 

Erőforrás-típus Jelentés
RT_ACCELERATOR Billentyűzet gyorsítótábla
RT_ANICURSOR Animált egérmutató
RT_ANIICON Animált ikon
RT_BITMAP Bittérkép
RT_CURSOR Eszközfüggetlen kurzor
RT_DIALOG Dialógusdoboz
RT_FONT Betűkészlet
RT_FONTDIR Betűkészlet-könyvtár
RT_GROUP_CURSOR Eszközfüggetlen egérmutató
RT_GROUP_ICON Eszközfüggetlen ikon (több változatban)
RT_ICON Eszközfüggetlen ikon (egy változatban)
RT_MENU Menü-definíció
RT_MESSAGETABLE Üzenettáblázat
RT_RCDATA Alkalmazás által definiált erőforrás (nyers bináris)
RT_STRING Sztring-táblázat
RT_VERSION Verzió-információ

Gyorsítótáblák (Accelerator tables)

Az gyorsítótáblák - a menükhöz hasonlóan - az alkalmazás funkcióhoz történő hozzáférést teszik lehetővé a felhasználó számára, mégpedig úgy, hogy bizonyos speciális billentyűkombinációk lenyomása esetén - szintén a menükhöz hasonlóan - bizonyos parancs-üzeneteket küldenek az alkalmazás részére, amelynek hatására az elkezdi a társított funkció végrehajtását. Tehát végső soron a gyorsítótáblák nem csinálnak mást, mint billentyűzet-üzeneteket fordítanak parancsüzenetekké az alább látható módon:

Egy alkalmazás tetszőleges számú gyorsítótáblát definiálhat, amelyeket a LoadAccelerator() API függvény segítségével tölthet be. A billentyűzet-üzenetek parancsokká fordításához az üzenet-feldolgozó ciklusban minden egyes alkalmazni kívánt gyorsítótáblára meg kell hívnia a TranslateAccelerator() függvényt, ami automatikusan felismeri az adott táblában definiált billentyűkombinációkat és azokat a megfelelő parancs-üzenetekre cseréli ki.
 

(folytatjuk)