Apelarea funcțiilor ferestrelor api

Din cartea C #. Sfaturi pentru programatori (pe scurt)

Codul care rulează sub CLR (Common Language Runtime, adică runtime-ul comun al limbajului) se numește cod gestionat. Codul care se execută în afara runtimei CLR se numește cod nesupravegheat. Un exemplu de cod de program neadministrat este funcțiile Win32 API, componente COM, interfețe ActiveX. În ciuda numărului mare de clase .NET Framework care conțin multe metode, programatorul trebuie să recurgă la codul neadministrat. Trebuie să spun că numărul apelurilor de cod neangajate scade odată cu lansarea fiecărei versiuni noi a .NET Framework. Microsoft speră că va veni timpul când întregul cod poate fi gestionat și sigur. Dar până acum, realitatea este că nu putem face fără a numi funcțiile Windows API. Dar mai întâi o mică teorie.







NET Framework cod gestionat poate provoca o funcție necontrolată a DLL (API funcție Windows) utilizând mecanismul Platform Invoke (abbr. P / Invoke). Pentru a aborda unele bibliotecă neupravlyamoyneupravlyaemoy DLL, aveți nevoie pentru a converti NET-obiecte în seturi de struct, char * și indicii la funcții, în conformitate cu limbajul C. Așa cum programatorii ar spune despre jargonul său - trebuie să Maresalului parametrii. Mai multe detalii despre Marshalling trebuie citite în documentație. Pentru a determina de DLL-funcții de C #, în primul rând trebuie să fie declarate (programatori care au experiență cu Visual Basic 6.0, sunt deja familiarizați cu această metodă). Pentru aceasta, utilizați atributul DllImport:

Uneori, în exemple, puteți veni, de asemenea, peste acest fel (lung si incomod): [System.Runtime.InteropServices.DllImport ( „User32.dll“)]. . dar este un amator.

Atributul DllImport îi spune compilatorului unde se află punctul de intrare, ceea ce vă permite să apelați funcția din locul potrivit. Trebuie să utilizați întotdeauna tipul IntPtr pentru HWND. HMENU și alți descriptori. Pentru LPCTSTR, utilizați String. și serviciile interop vor efectua marshalizarea automată a System.String în LPCTSTR înainte de transferul la Windows. Căutările compilator pentru funcția SetWindowText de mai sus în fișierul User32.dll, și înainte de apelul convertește automat șirul la LPTSTR (TCHAR *). De ce se întâmplă acest lucru? Pentru fiecare tip, C # definește propriul tip, care este folosit pentru tipul de marshall implicit. Pentru șiruri de caractere, acesta este LPTSTR.

Apelarea funcțiilor API Windows cu șir de ieșire char *

Să presupunem că trebuie să sunăm la funcția GetWindowText. care are un char char output *. În mod implicit, LPTSTR este utilizat pentru șiruri de caractere. dar dacă folosim System.String. după cum sa menționat mai sus, nu se va întâmpla nimic, deoarece clasa System.String nu vă permite să modificați șirul. Trebuie să utilizați clasa StringBuilder. care vă permite să schimbați linia.

Tipul utilizat pentru marcharea de tip StringBuilder implicit este de asemenea LPTSTR. dar acum GetWindowText poate modifica string-ul dvs. foarte:







Astfel, răspunsul la întrebarea cum se numește o funcție care are un parametru șir de ieșire va fi - folosiți clasa StringBuilder.

Schimbați tipul implicit de marshaling

De exemplu, dorim să apelați funcția GetClassName. care ia parametrul LPSTR (char *) chiar și în versiunile Unicode. Dacă treceți un șir, limbajul de rulare comun (CLR) îl convertește în seria TCHAR. Dar cu atributul MarshalAs, puteți suprascrie ceea ce este oferit implicit:

Acum, că numiți GetClassName. NET va transmite șirul dvs. ca caractere ANSI, nu "caractere mari".

Apelarea funcțiilor care necesită o structură

Luați, de exemplu, funcția GetWindowRect. care înregistrează în structura RECT coordonatele ecranului ferestrei. Pentru a apela funcția GetWindowRect și a trimite o structură RECT, trebuie să utilizați structul în combinație cu atributul StructLayout:

Lucrul cu funcțiile de apel invers în C #

Pentru a utiliza funcțiile scrise în C # ca funcții de apel invers Windows, delegații trebuie să fie utilizați (delegat).

Declarând tipul delegaților, puteți scrie o coajă pentru funcția Windows API:

Dat fiind faptul că linia delegată declară pur și simplu un tip de delegat, delegatul trebuie să fie prezentat în clasă:

și apoi treceți-l în coajă:

Cititorii uimitori vor observa că am lăsat o problemă cu lparam.

În C, dacă EnumWindows primește LPARAM, Windows va notifica funcția de apel invers cu acest LPARAM. De obicei, lparam este un pointer la o structură sau clasă care conține informațiile de context de care aveți nevoie pentru a efectua operațiunile. Dar rețineți: în .NET cuvântul "pointer" nu poate fi pronunțat! Deci, ce faci? Puteți să vă declarați lparam ca IntPtr și să utilizați GCHandle ca shell:

Nu uitați să sunați gratuit când ați terminat! Uneori în C # trebuie să eliberați memoria. Pentru a accesa lparamul "pointer" în interiorul enumeratorului, utilizați GCHandle.Target.

Mai jos este clasa pe care am scris-o, care încapsulează EnumWindows într-o matrice. În loc să vă grăbiți cu toți acești delegați și apeluri, scrieți:

Un mic program ListWin (Anexa ListWin.cs), pe care am scris-o pentru transferul de ferestre de nivel superior, puteți vizualiza liste hWnd, nume de clase, titluri, și / sau dreptunghiuri de ferestre folosind RECT sau dreptunghi. Codul sursă al ListWin nu este afișat pe deplin; întregul cod sursă poate fi descărcat de la legătura de la sfârșitul articolului.

Crearea propriei biblioteci gestionate

Puteți crea propria bibliotecă gestionată, din care puteți apela funcțiile API Windows. Pentru a face acest lucru, Visual Studio oferă opțiuni speciale. Un nou proiect este creat ca o bibliotecă de clasă (Class Library). Ansamblul va primi automat extensia dll. Utilizarea bibliotecilor gestionate în codul gestionat este ușor. Pentru a face acest lucru, adăugați un link (folosind meniul Project | Add Reference ...) la ansamblul bibliotecii, specificând locația ansamblului în caseta de dialog corespunzătoare. După aceea, Visual Studio copiază ansamblul în directorul unde este localizat codul. Mai departe, în codul programului se folosește fie instrucțiunea folosind. sau numele complet al modulului de bibliotecă cu notație punctuală. Toate clasele și metodele de bibliotecă sunt pregătite pentru utilizare în codul programului.

De asemenea, puteți utiliza linia de comandă. Pentru a compila clasa Win32API.cs, tastați:

Ca rezultat, veți avea un fișier Win32API.dll creat pentru orice proiect din C #.

Un exemplu de creare a unei biblioteci și de utilizare a funcțiilor API-ului Windows este localizat în folderul Win32 de pe discul care însoțește cartea.

Exemple de utilizare a funcțiilor API

Cunoscut pe scurt cu teoria, să ne îndreptăm spre exemple concrete. În capitolele anterioare, am menționat deja un exemplu de utilizare a funcțiilor API Windows pentru a rezolva diferite probleme. Să luăm în considerare câteva sfaturi utile, care nu au intrat în alte capitole.

concluzie

În ciuda numărului mare de clase .NET Framework disponibile, programatorul trebuie să recurgă la apeluri la funcțiile de sistem ale API-ului Windows. În folderul Win32Help de pe CD-ROM-ul care însoțește cartea, veți găsi o versiune demo a ghidului funcțiilor API Windows pentru .NET Framework. Dacă vă place acest director, atunci puteți achiziționa versiunea completă pe site-ul meu.

cerere

Win32API.cs

ListWin.cs

Informații suplimentare







Articole similare

Trimiteți-le prietenilor: