Windows, Winapi, Delphi

Când este încă necesar

Există momente când un programator dorește să renunțe la VCL. Cel mai des, desigur, acest lucru se întâmplă din cauza economiei, astfel încât exe nu se dovedește a fi atât de mare (că în epoca actuală este practic lipsită de sens doar dacă sunteți angajat într-o zonă specială, de exemplu, demoscena). Dar VCL are încă o limitare neplăcută - este una cu filet. Windows în sine suportă perfect multi-threading, și atunci când doriți ferestre paralele cinstit, trebuie să utilizați API-ul.







Cum se realizează acest lucru

Ce face un programator care lucrează întotdeauna cu VCL, și apoi are nevoie de ferestre pe API? El merge la Google pentru exemple și în mijlocul descrierii funcțiilor. Și pe Internet, toate exemplele sunt folosite pentru o programare procedurală. Iar atunci când un programator înșelă un astfel de cod - zona de program cu acest cod se transformă într-un monstru. Și cel mai important - nu este foarte clar cum se poate pune acest cod pe conceptul de oop. De exemplu, cum se face în VCL. Ar fi de dorit să creați o fereastră prin TMyWindow.Create, ar fi de dorit să lucrați cu o fereastră în interiorul unei clase, ca în VCL. Ar fi de dorit, la urma urmei, să procesăm mesajele de mesaje.

Și ce vom realiza

În acest articol, voi inventa o bicicletă pentru a încerca să facă ceva similar structurii VCL, și anume - să punem ferestrele noastre în conceptul de OOP. Ei bine, voi descrie unele dintre principiile Windows și mesaje de fereastră. Ei bine, din moment ce eu cred că prodelyvat orice lucrare necesară pentru beneficiul, vom încerca să facă cod prietenos refolosite, care pot fi accesate cu ușurință și modificată în proiectele sale viitoare și de a utiliza, utilizarea, l utilizați.

Cum lucrează Windows în Windows

Oricine a făcut vreodată o fereastră WinAPI înseamnă, știe ce este nevoie pentru a crea o funcție care va veni mesajele noastre, înregistrați clasa cu această funcție, apoi creați o fereastră bazată pe clasa sa și, în cele din urmă, în fluxul de cod pentru a face o buclă infinită, care ar fi angajat doar în faptul că a ales mesaje de fereastră. Și este foarte inconfortabil. În primul rând, pentru că nu este clar cât de frumos este codul (sau chiar mai bun din punctul de vedere al OOP) de a crea 3, 4 sau mai multe ferestre. Ciclul este unul pentru noi, iar funcția de fereastră este, de asemenea, una.

În ciuda faptului că scriu, spun ei, Windows trimite mesaje pe fereastră - nu este chiar adevărat. Windows trimite mesaje către flux. Toate ferestrele create - sunt atașate la firul specific în care a fost apelată funcția CreateWindow. Este important să înțelegem că, dacă am creat o fereastră în firul curent, toate mesajele vor fi procesate numai în contextul acestui thread. Acesta este modul în care Windows implementează lucrări multi-threaded cu ferestre. Deci, dacă avem 10 ferestre create într-un fir, atunci toate aceste mesaje vor veni într-un singur fir și ar trebui selectate într-un singur ciclu al acestui flux. În continuare, la selectare, puteți specifica fie un filtru manual (al doilea parametru este GetMessage), fie devine clar în funcția ferestrei în care fereastră a apărut mesajul. Dar nu este necesar să procesați mesajele de fereastră, dar mesajele de flux, adică Al doilea parametru GetMessage ar trebui să fie în 0. Și acest lucru este important, pentru că trebuie să rezolvăm mesajul WM_QUIT. Acest mesaj nu va ajunge niciodată în nicio fereastră și singura opțiune posibilă de a selecta acest mesaj este să treacă 0 la al doilea parametru al funcției GetMessage. De ce avem nevoie de acest mesaj ciudat. Și este necesar să ieșiți corect din buclă. Când facem o selecție cu GetMessage, funcția ne întoarce întotdeauna adevărată, dar când GetMessage alege din coada WM_QUIT - returnează false. Dacă dorim brusc să ieșim din bucla ferestrei o dată pentru totdeauna, atunci trebuie să sunăm PostQuitMessage (ExitCode) în același fir; iar mesajul WM_QUIT va fi în coada de așteptare pentru firul curent.







Cum lucrează ferestrele în VCL

În plus, aplicația TA este îngroșată cu alte funcționalități și este foarte dificil să rescrieți codul VCL pentru suportul multi-filetat. Din fericire, nu vom face acest lucru, vrem să abandonăm VCL.

Reflecții asupra arhitecturii

Totul este în general. Dacă unele detalii sunt neclar - sper că implementarea va deveni mai clară.

Din moment ce TApps are unul pentru fiecare thread, trebuie să stocăm o listă, vom avea o matrice, o vom numi: Aplicații: matrice de TApp; Deoarece apelurile către această matrice vor fi din mai multe fire, este important să se sincronizeze accesul la ele. Pentru a face acest lucru, vom porni secțiunea critică: AppCS: TRTLCriticalSection;

Toate acestea sunt aranjate în implementarea secțiunii modulului, astfel încât alte module să nu aibă acces la datele noastre.

În implementarea aceleiași clase:

Acesta va funcționa corect, iar când fereastra este închisă, programul nostru se va termina.

Dar despre multithreading?

Rămâne pentru noi să implementăm un exemplu simplu de funcționare a ferestrelor în mai multe fire. De exemplu, voi folosi clasa TThread, care se află în Classes.pas. Înțeleg că acest modul ne distruge minimalismul la rădăcină, dar sarcina mea este să arăt cum funcționează ferestrele noastre convenabil. Poate că voi avea timp și voi scrie un articol similar despre fire și OOP. Deci, iată codul pentru o aplicație simplă multi-filetat cu două ferestre:

Asta e tot. Începem, avem 2 ferestre. Când cele două ferestre sunt închise, aplicația se termină.

Mai sus vorbeam despre un modul prietenos reutilizat. Din păcate, funcționalitatea modulului este foarte mică, cel puțin nu știe cum să creeze ferestre copil. De asemenea, nu există nici o lucrare cu clase Windows globale. Nici nu putem crea un buton fără a modifica modulul. Acest modul ar trebui considerat doar ca unul de bază, arătând modul în care este posibilă încorporarea frumosului WinAPI în clase utilizând caracteristicile Delphi și acest modul poate fi ușor modificat într-un mod convenabil. Se implementează pachetul funcției de fereastră cu clasele, ceea ce înseamnă că sarcina mea poate fi considerată rezolvată. VCL Delphi standard funcționează într-un mod foarte asemănător, care este doar cu multithreading la ferestrele de probleme VCL.

Voi încerca foarte curând să întocmesc un addendum la acest articol. Această adăugire va reprezenta modulul meu și descrierea claselor, care are mult mai multe oportunități decât cea scrisă "pe genunchi".

Mai ales pentru Regatul Delphi







Articole similare

Trimiteți-le prietenilor: