Hívja a Windows api függvényeket

A C # könyvből. Tippek a programozók számára (röviden)

A CLR alatt futó kódot (Common Language Runtime, azaz a közös nyelv futási ideje) sikeres kódnak hívják. A CLR futási idején kívül futó kódot nem kezelt kódnak nevezik. A nem kezelt programkód például a Win32 API funkciók, COM összetevők, ActiveX interfészek. Annak ellenére, hogy nagyszámú .NET Framework osztályok számos módszert tartalmaznak, a programozónak továbbra is igénybe kell vennie a nem kezelt kódot. Meg kell mondanom, hogy a nem kezelt kódhívások száma csökken a .NET-keretrendszer minden új verziójának kiadásával. A Microsoft reméli, hogy eljön az idő, amikor az összes kód kezelhető és biztonságos. De eddig a valóság az, hogy nem tudunk anélkül hívni a Windows API-funkciókat. De először egy kis elmélet.







A felügyelt .NET-keretrendszer kódja egy nem kezelt függvényt hívhat le a DLL-ből (a Windows API-függvényből) a Platform Invoke speciális mechanizmus (P / Invoke) használatával. Annak érdekében, hogy bizonyos neupravlyamoyneupravlyaemoy DLL könyvtár, meg kell konvertálni a .NET-objektumok a struct készletek, char * és mutatókat a funkciókat, ahogy azt a nyelvet C. programozók mondaná az ő zsargonban - meg kell marsall paramétereket. További részletek a Marshallingről olvassa el a dokumentációt. A C # -es DLL-funkció hívásához először nyilatkoznia kell (a Visual Basic 6.0 alkalmazással rendelkező programozók már ismerik ezt a módszert). Ehhez használja a DllImport attribútumot:

Néha, a példákban, akkor is találkoznak ezzel a módszerrel (a hosszú és kényelmetlen): [System.Runtime.InteropServices.DllImport ( „User32.dll”)]. . de ez egy amatőr.

A DllImport attribútum megmondja a fordítónak, ahol a belépési pont található, ami lehetővé teszi, hogy a funkciót a megfelelő helyről hívja. Mindig az IntPtr típust használja a HWND-hez. HMENU és bármely más leíró. Az LPCTSTR esetében használja a String-ot. és az interop szolgáltatások automatikusan végrehajtják a System.String automatikus lebonyolítását a LPCTSTR-ben, mielőtt Windows-ra továbbítanák. A fordító a User32.dll fájlban a fenti SetWindowText függvényt keresi, majd konvertálás előtt automatikusan átalakítja a stringet LPTSTR (TCHAR *) -ra. Miért történik ez? Minden típus esetében a C # a saját típusát határozza meg, amelyet az alapértelmezett marshalltípushoz használnak. A húrok esetében ez LPTSTR.

A Windows API funkcióinak meghívása a kimeneti karakterlánccal char *

Tegyük fel, hogy hívnunk kell a GetWindowText függvényt. amely karakterlánc karakterláncot tartalmaz *. Alapértelmezés szerint az LPTSTR karakterláncokat használják. de ha a System.Stringet használjuk. mint fent említettük, semmi sem fog történni, mert a System.String osztály nem teszi lehetővé a karakterlánc módosítását. Használnia kell a StringBuilder osztályt. amely lehetővé teszi a vonal megváltoztatását.

A StringBuilder marshallinghez használt típus alapértelmezés szerint LPTSTR is. de most a GetWindowText módosíthatja a nagyon stringet:







Így a válasz arra a kérdésre, hogy hogyan hívhatunk egy olyan függvényt, amely egy kimeneti karakterlánc paraméterrel rendelkezik - a StringBuilder osztály használata.

Módosítsa a hajózás alapértelmezett típusát

Például hívjuk a GetClassName funkciót. amely az LPSTR (char *) paramétert még Unicode verziókban is felhasználja. Ha átadja a karakterláncot, akkor a közös nyelvi futásidejű (CLR) átváltja a TCHAR sorozatba. A MarshalAs attribútummal azonban felülbírálhatja az alapértelmezett szolgáltatásokat:

Most, hogy felhívja a GetClassName nevet. A NET átadja a karakterláncot ANSI karakterekként, nem pedig "széles karakterekként".

Olyan hívófunkciók, amelyekhez struct szükséges

Vegye például a GetWindowRect funkciót. amely a RECT struktúrában rögzíti az ablak képernyő koordinátáit. A GetWindowRect funkció hívásához és egy RECT struktúra átviteléhez a struct típust a StructLayout attribútummal együtt kell használni:

A visszahívási funkciók használata a C #-ban

A C # -ként Windows-visszahívási funkcióknál írt funkciók használatához a küldötteket (delegált) kell használni.

A küldött típusának deklarálása esetén a Windows API-funkcióhoz héjat írhat:

Mivel a delegált vonal egyszerűen egy delegált típust deklarál, a küldöttnek magának az osztálynak kell lennie:

majd átadja a héjnak:

Az elgondolkodtató olvasók észre fogják venni, hogy problémát okoztak az iparámmal.

A C-ben, ha az EnumWindows-t LPARAM-ra adják, a Windows értesíti a visszahívási funkciót ezzel a LPARAM-szal. Az lparam általában egy mutató egy olyan struktúrához vagy osztályhoz, amely tartalmazza a műveletek elvégzéséhez szükséges környezetinformációkat. De ne feledje: a .NET-ben a "mutató" szót nem lehet kiejteni! Mit csinálsz? A lparamot IntPtr-ként deklarálhatod, és használhatod a GCHandle-t héjként:

Ne felejtsd el hívni az ingyeneset, ha kész vagy! Néha a C #-ben meg kell szabadítanod a memóriát. Ahhoz, hogy a "pointer" lparam belépjen a számlálóba, használja a GCHandle.Target parancsot.

Az alábbiakban az I. osztály írta, amely az EnumWindows-ot egy tömbbe foglalja. Ahelyett, hogy összezavarna mindezekkel a küldöttekkel és visszahívásokkal, írja:

Egy kis program ListWin (Függelék ListWin.cs), írtam az átadás felső szintű ablakok, megnézheti HWND listákat, osztály neveket, címeket és / vagy téglalap ablakokat RECT vagy téglalap. A ListWin forráskódja nem teljesen látható; az összes forráskód letölthető a cikk végén található linkről.

Saját kezelt könyvtár létrehozása

Készíthet saját kezelt könyvtárat, ahonnan hívhatja a Windows API funkcióit. Ehhez a Visual Studio speciális lehetőségeket kínál. Egy új projekt létrehozása osztálykönyvtárként (Class Library). A rendszer automatikusan megkapja a kiterjesztést. A kezelt könyvtárak kezelése egyszerű. Ehhez hozzon létre egy linket (a Project | Add Reference ... menü használatával) a könyvtárszerelvényhez, és adja meg a megfelelő párbeszédablakban a telephely helyét. Ezután a Visual Studio átmásolja az összeszerelést a könyvtárba, ahol a kód található. A program kódjában a használó utasítás is használható. vagy a könyvtári modul teljes neve pontjelöléssel. Minden könyvtári osztály és módszer készen áll a programkód használatára.

Használhatja a parancssort is. A Win32API.cs osztály összeállításához írja be:

Ennek eredményeképpen létrejön egy Win32API.dll fájl a C # projekthez.

Példa egy könyvtár létrehozására és a Windows API funkcióinak használatára a könyvhez tartozó lemez Win32 mappájában található.

Példák az API funkciók használatára

Röviden megismertesse az elméletet, forduljunk konkrét példákhoz. Az előző fejezetekben már említettem egy példát a Windows API funkcióinak használatára különböző problémák megoldására. Vegyünk néhány hasznos tanácsot, amely nem lépett be más fejezetekbe.

következtetés

A rendelkezésre álló .NET-keretosztályok nagy száma ellenére a programozónak továbbra is igénybe kell vennie a Windows API rendszerfunkcióit. A könyvet kísérő CD-ROM Win32Help mappájában megtalálja a .NET-keretrendszer Windows API-funkcióinak útmutatójának demo verzióját. Ha tetszik ez a könyvtár, akkor megvásárolhatja teljes verzióját webhelyemen.

kérelem

Win32API.cs

ListWin.cs

További információk




Kapcsolódó cikkek