Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • Internet, Wi-Fi, rețele locale
  • Rezumat: Utilizarea interfețelor deschise ale mediului de programare Delphi. Recomandări pentru crearea interfețelor utilizator în descrierea interfeței Delphi Delphi

Rezumat: Utilizarea interfețelor deschise ale mediului de programare Delphi. Recomandări pentru crearea interfețelor utilizator în descrierea interfeței Delphi Delphi

Am o problemă la utilizarea clasei Delphi din codul C++. delphi dll demo care exportă o funcție care returnează un obiect.
codul meu Delphi Dll arată astfel:

Biblioteca DelphiTest; // folosește partea.... tip IMyObject = procedura de interfață DoThis(n: Integer); funcția DoThat: PWideChar; Sfârșit; TMyObject = class(TInterfacedObject,IMyObject) procedura DoThis(n: Integer); funcția DoThat: PChar; Sfârșit; // Implementarea TMyObject merge aici ... procedura TMyObject.DoThis(n: Integer); begin showmessage ("apelați metoda DoThis cu "+intToStr(n) +"parametru"); Sfârșit; funcția TMyObject.DoThat: PChar; begin showmessage(„apelați funcția DoThat”); Rezultat:= Pchar("Buna, sunt Dothat"); Sfârșit;

// exportă funcția DLL:

Funcția CreateMyObject: IMyObject; stdcall;export; var txt: TextFile; începe AssignFile(txt,"C:\log.log"); resetare(txt); Writeln(txt,"bună ziua"); Rezultat:= TMyObject.Create; Sfârșit; exportă CreateMyObject;

în proiectul meu C++ am declarat interfața IMyObject astfel:

Clasa IMyObject ( public: IMyObject(); virtual ~IMyObject(); virtual void DoThis(int n) = 0; virtual char* DoThat() = 0; );

iar funcția mea principală este următoarea:

Typedef IMyObject* (__stdcall *CreateFn)(); int main() ( HMODULE hLib; hLib = LoadLibrary(L"DelphiTest.dll"); assert(hLib != NULL); // trece !! CreateFn pfnCreate; pfnCreate = (CreateFn)GetProcAddress((HINSTANCE)hLib, "CreateMyObject "); if (pfnCreate == NULL) ( DWORD errc = GetLastError(); printf("%u\n", errc); // primește eroarea 127 ) else( printf("încărcare de succes\n"); ) IMyObject* objptr = pfnCreate(); objptr->DoThis(5); FreeLibrary(hLib); int in; scanf_s("%i", &in); return 0; )

în acest exemplu, am primit o eroare de rulare când încerc să accesez funcția exportată. erori de linie:
IMyObject* objptr = pfnCreate();

Îmi puteți spune ce este în neregulă cu exemplul meu.
și dacă este posibil orice exemplu de lucru pentru accesarea unei clase Delphi (într-un DLL) din codul C++.

Soluţie

Prima problemă este apelarea convenției metodei. Interfața Delphi folosește un registru care este o convenție de apelare specifică Delphi. folosind stdcall De exemplu, pentru metodele de interfață.

Următoarea problemă este în C++. Interfața dvs. C++ trebuie să derive din IUnknown . De asemenea, nu trebuie să declare un constructor sau un destructor.

În afară de asta, codul tău Delphi exportă PWideChar care nu se mapează la char* . Se mapează la wchar_t* .

Privind mai departe, returnarea unui PChar funcționează excelent aici, deoarece implementarea dvs. returnează un literal. Dar un cod mai serios va dori probabil să folosească un șir alocat dinamic, moment în care designul tău este defectuos.

Rețineți că trebuie să fiți un administrator superior pentru a crea un fișier în rădăcina unității de sistem. Deci acesta este un alt punct potențial de eșec.

Mă aștept să fie și alte erori, dar asta e tot ce am găsit până acum.

Articolul a fost scris pe baza rezultatelor analizelor de programe scrise de tinerii dezvoltatori ai grupului nostru.

Aranjați corect secvența de comutare a componentelor

Mulți utilizatori, în special cei care au lucrat anterior în DOS, au obiceiul de a comuta între câmpurile de intrare nu cu mouse-ul, ci folosind tastatura cu tasta Tab. În plus, este mult mai rapid decât selectarea fiecărui câmp cu mouse-ul. Prin urmare, ordinea de comutare a componentelor trebuie setată corect. Acest lucru se aplică atât componentelor din interiorul tuturor componentelor containerului (panouri, GroupBoxes și altele asemenea), cât și componentelor containerului în sine, dacă există mai multe dintre ele pe formular.

Ordinea de comutare a componentelor din interiorul containerului este stabilită de proprietatea TabOrder. Prima componentă care devine activă este cea cu TabOrder egal cu 0, a doua cu 1 și așa mai departe, până când toate componentele au fost repetate. În plus, componenta are o proprietate TabStop, care indică dacă componenta va primi focalizare la comutarea cu tasta Tab. Dacă trebuie să dezactivați comutarea la orice componentă, setați TabStop = false pentru aceasta. În acest caz, se va putea trece la această componentă doar cu ajutorul mouse-ului.

Sunt momente când utilizatorii care sunt obișnuiți să comute o anumită cheie într-un program, din obișnuință, continuă să o folosească în altele. Acest lucru se întâmplă adesea cu utilizatorii 1C, unde tasta Enter poate fi folosită pentru a naviga prin câmpurile de introducere. Ei bine, să le oferim această oportunitate în programele noastre dacă o cer. Setați proprietatea KeyPreview a formularului la true și scrieți handlerul de evenimente OnKeyPress:

Procedura TForm1.FormKeyPress(Sender: TObject; var Key: Char);
începe
dacă ord(key)=vk_Return atunci
Form1.SelectNext(PriemForm.ActiveControl, adevărat, adevărat);
Sfârșit;

Un astfel de handler oferă o tranziție prin elementele formularului atunci când este apăsată tasta Enter. Trebuie remarcat faptul că această metodă nu va funcționa cu butoane, deoarece apăsarea Enter pe un buton face ca acesta să fie apăsat, în timp ce apăsarea Tab transferă focalizarea de intrare către următoarea componentă din secvența de comutare.

Butoane implicite

Toți aceiași utilizatori se obișnuiesc rapid cu faptul că, în casetele de dialog ale aplicației, de regulă, puteți confirma alegerea cu tasta Enter și anulați cu tasta Esc. Să nu-i dezamăgim în programele noastre, mai ales că este foarte ușor de făcut. Pentru butonul Enter, setați proprietatea implicită la true. Pentru un buton care răspunde la Esc, setați proprietatea Cancel la true. Si asta e.

da sau nu

Toate casetele de dialog care solicită acțiuni utilizator trebuie să aibă cel puțin două butoane: confirmarea unei acțiuni și refuzul unei acțiuni (Da/Nu, Salvare/Anulare etc.). Acțiunea poate fi anulată prin închiderea ferestrei cu butonul [X] din titlul ferestrei. Este invalid dacă există un singur buton pentru confirmarea acțiunii, iar pentru refuz ar trebui să se închidă fereastra cu butonul [X] din titlu, sau nu există nicio posibilitate de refuz. Acest lucru derutează utilizatorul, provocând o întrebare logică: cum să refuzi?

De asemenea, nu uitați de cele spuse mai sus în paragraful „Butoane implicite”.

Toate casetele de dialog ar trebui să se deschidă în centrul ecranului

Centrate în loc de locul în care au fost create în modul design. În primul rând, este mai vizual și, în al doilea rând, elimină automat problema diferitelor rezoluții de ecran pentru diferiți utilizatori.

Se face o excepție dacă caseta de dialog nu este modală și, ca urmare a muncii utilizatorului în această fereastră, apar imediat modificări în fereastra principală (de exemplu, filtrarea unui set de date, redesenarea graficelor etc.).

Dimensiunile ferestrelor nu trebuie să depășească dimensiunile ecranului.

În niciun caz. Este o rușine când o parte a ferestrei iese din ecran. Această cerință nu depinde de rezoluția ecranului utilizatorului, de exemplu. scuze precum „Lasă-i să pună o rezoluție mai mare” nu funcționează.

Redimensionarea corectă a elementelor ferestrei

Elementele ferestrei trebuie să redimensioneze sau să se miște corect atunci când fereastra este redimensionată, când fereastra este maximizată și când fereastra este restaurată după ce a fost maximizată.

Totul este mereu vizibil

Reducerea dimensiunii ferestrei nu ar trebui să ducă la dispariția elementelor ferestrei și, de preferință, nu ar trebui să ducă la apariția barelor de defilare (scroller) ale ferestrei în sine. Puteți limita dimensiunea minimă a ferestrei astfel încât toate elementele să fie vizibile și accesibile. Dacă nu este posibil să plasați componentele astfel încât toată lumea să fie vizibilă în fereastră, puteți folosi file (de tip PageControl) pentru a împărți componentele în grupuri. Nici scuzele despre rezoluția ecranului nu sunt ratate.

Sugestii peste tot, indicii mereu

Pentru butoane, în special pe barele de instrumente (cum ar fi ToolBar), ar trebui oferite indicii, astfel încât să fie întotdeauna clar de ce este necesar acest buton sau acela.

Spectrul de culori

Nu este necesar să pictați componentele pe formă în toate culorile curcubeului. Acest lucru obosește ochii și împrăștie atenția utilizatorului. Nu pare „mișto”. Evidențierea este utilizată atunci când este necesar să atrageți atenția utilizatorului asupra unui anumit element sau a unei anumite părți a ferestrei. De exemplu, puteți colora intrările cu erori în culoarea roșu deschis sau, dimpotrivă, în culoarea verde deschis a intrărilor, a căror verificare a avut succes.

Concluzie

Există o metodă foarte bună care vă permite să găsiți deficiențele programului în general și ale interfeței în special. Este simplu: imaginează-te în locul utilizatorului și timp de o jumătate de oră încearcă să lucrezi așa cum lucrează el. Este și mai bine dacă utilizatorul dvs. este la îndemână (de exemplu, lucrează în aceeași organizație). În acest caz, stai lângă el, sau mai bine zis în locul lui, și încearcă să-și faci treaba. Introduceți date, modificați-le, afișați rapoarte etc. Dacă nu știți cum să o faceți corect, întrebați utilizatorul. Nu faceți una sau două operațiuni de același tip, ca în modul de depanare, ci 20-30 sau chiar mai multe operațiuni diferite, într-o ordine diferită. Uitați să introduceți ceva sau introduceți-l incorect și vedeți cum reacționează programul la el. Veți vedea rapid punctele slabe ale programului dvs.

Autorul articolului a automatizat activitatea comisiei de admitere la universitate, iar în primul an de implementare a programului, a petrecut 3-4 ore pe zi la comisia de admitere, înregistrând solicitanții, completând datele lor personale și dându-le acestora rapoarte de examen. Și în timpul de lucru rămas, s-au corectat erori și neajunsuri. Crede-mă, anul viitor practic nu mai sunt probleme. La fel a fost și cu introducerea modulului de personal.

Astfel, țineți cont de experiența utilizatorului. Să fie ușor și plăcut pentru ei să lucreze cu programele dvs.

Programarea orientată pe obiecte (OOP), pe lângă conceptul de clasă, oferă și conceptul fundamental de interfață.

Ce este o interfață și care sunt caracteristicile lucrului cu ea în limbajul de programare Delphi?

O interfață este o construcție semantică și sintactică în codul de program folosit pentru a specifica serviciile furnizate de o clasă sau componentă (Wikipedia).

De fapt, o interfață definește o listă de proprietăți și metode care ar trebui utilizate atunci când se lucrează cu o clasă care implementează această interfață, precum și semnătura acestora (nume, tip de date, parametri acceptați (pentru proceduri și funcții), etc.). Astfel, o clasă care implementează o interfață trebuie neapărat să implementeze toate componentele sale. Mai mult, în strictă conformitate cu modul în care sunt descrise în el.

Foarte des, interfețele sunt comparate cu clase abstracte, dar pentru toate asemănările, această comparație nu este în întregime corectă. În clasele abstracte, este disponibil cel puțin controlul asupra vizibilității membrilor. În același timp, domeniile nu sunt definite pentru interfețe.

Interfețele vă permit să faceți arhitectura mai flexibilă, deoarece unifică accesul la o anumită funcționalitate și, de asemenea, vă permit să evitați o serie de probleme asociate cu moștenirea clasei (interfețele pot fi, de asemenea, moștenite una de la alta).

Delphi folosește cuvântul cheie interfață pentru a declara o interfață. Acesta este același cuvânt cheie care definește secțiunea modulului care poate fi accesată din exterior (între interfață și cuvintele cheie de implementare). Cu toate acestea, atunci când declarați o interfață, este utilizată o sintaxă diferită, similară cu declararea claselor.

Delphi/Pascal

IMyNewInterface = procedura de interfata InterfaceProc; Sfârșit;

IMyNewInterface =interfață

procedura InterfaceProc ;

Sfârșit ;

Astfel, sintaxa declarației interfeței în sine nu are diferențe fundamentale față de alte limbaje de programare (funcțiile de sintaxă bazate pe Pascal nu contează). În același timp, implementarea interfețelor are o serie de trăsături caracteristice.

Faptul este că interfețele Delphi au fost introduse inițial pentru a suporta tehnologia COM. Prin urmare, interfața IInterface, care în Delphi este strămoșul tuturor celorlalte interfețe (un fel de analog al TObject), conține deja trei metode de bază de lucru cu această tehnologie: QueryInterface, _AddRef, _Release. Ca rezultat, dacă o clasă implementează orice interfață, atunci trebuie să implementeze și acele metode. Chiar dacă această clasă nu este proiectată să funcționeze cu COM.

Datorită acestei caracteristici a interfeței IInterface, în Delphi utilizarea interfețelor, în cele mai multe cazuri, duce la adăugarea de caracteristici evident neutilizate la clasă.

Există o clasă de bibliotecă TInterfaceObject, care conține deja implementarea acestor metode și, atunci când se moștenește de la aceasta, nu este nevoie să le implementați singur. Dar, deoarece Delphi nu acceptă moștenirea mai multor clase, utilizarea sa cauzează adesea doar complexitate suplimentară în proiectarea și implementarea funcționalității deja necesare.

Toate acestea au dus la faptul că, în ciuda tuturor posibilităților oferite de interfețe, utilizarea lor practică în Delphi aproape că nu a depășit lucrul cu COM.

Fiind optimizate pentru a lucra în principal cu această tehnologie, interfețele, sau mai bine zis funcționalitatea și restricțiile arhitecturale pe care le adaugă fără greș, nu se justifică atunci când rezolvă alte probleme.

Prin urmare, mulți programatori Delphi sunt încă, de fapt, lipsiți de un instrument puternic și flexibil pentru dezvoltarea arhitecturii aplicațiilor.

doar pentru rezultate

respectarea strictă a termenelor limită

Transparenţă

implementarea proiectului

suport tehnic cadou

Programare, îmbunătățiri, consultații pe 1C

Cum lucrăm

1. Discutam problema telefonic. Dacă aveți acces la distanță - afișați pe ecranul computerului.

2. Evaluăm munca în ruble dacă proiectul este mare, dacă nu - numărul aproximativ de ore.

3. Ne facem treaba.

4. Acceptați munca în programul dumneavoastră, dacă există neajunsuri, le corectăm.

5. Noi emitem o factura, tu platesti.

Costul muncii

1. Toate lucrările sunt împărțite în 3 categorii: consultație, actualizarea unei configurații tipice, elaborarea sau programarea unui nou raport, procesare, butoane etc.

3. Pentru munca de peste 10 ore se pregateste in prealabil o sarcina tehnica cu descrierea si costul lucrarii. Lucrarea începe după aprobarea TOR cu dvs.

Suport tehnic

1. Dacă găsiți erori în lucrările acceptate anterior, în termen de 3 luni, le corectăm gratuit.

2. Pentru clienții obișnuiți, remediam orice neajunsuri în activitatea noastră gratuit în decurs de un an.

Programe pentru gestionarea afacerii dvs.

Cumpărați 1C:Enterprise

Suntem dealer oficial al 1C, puteți achiziționa diverse produse software și licențe de la noi. Pe lângă cumpărarea unei „cutie”, vă vom ajuta să configurați programul, să consultați și să faceți setările de bază.

  • Contabilitate
  • Automatizarea magazinului
  • Angro
  • Ajutorul pentru instalare și configurarea inițială este inclus în pachet!
  • Ajustarea configurațiilor la nevoile clientului, dezvoltarea de noi module în lipsa funcțiilor necesare în configurația standard.
1c contabilitate 1C: Managementul comerțului 1C: Comerț cu amănuntul 1C: Managementul salarizării și al resurselor umane
De la 3300 de ruble. De la 6700 rub. De la 3300 de ruble. De la 7400 rub.

Furnizarea unui server.

Server de configurare instantanee + 1C.

Fără server? Nu contează, vom selecta și vom configura rapid un server în „cloud”. Pentru o taxă mică, obțineți o soluție foarte fiabilă.

  • Disponibilitate 24/7
  • Nu este nevoie să vă păstrați propriul administrator de sistem (economiile vor acoperi costul serverului dvs.).
  • Configurare și instalare rapidă a 1C pe server, în 3 zile vei avea deja un sistem complet funcțional.
  • În orice moment, puteți trece la un server local dacă soluția nu vă convine.

SMS de la 1C

Doriți ca clienții să învețe din timp despre promoții și reduceri? Clienții nu se întorc? Configurați trimiterea de SMS-uri direct de la 1C!

Compania noastră va putea configura rapid trimiterea de SMS-uri către clienții dvs. direct de la 1C. Exemple de evenimente care pot fi automatizate:

  • Recunoștință pentru achiziția și acumularea de bonusuri imediat după următoarea achiziție.
  • Acumularea de bonusuri pe card ca cadou pentru o zi de naștere/o altă zi importantă sau de sărbătoare.
  • Notificare depozit.
  • Expirarea voucherului cadou.
  • Notificare de primire a plății anticipate și rezervare a mărfurilor.
  • Adresa cu indicatii catre magazin/birou, numere de telefon.
  • etc.

Setarea în 1C poate fi făcută de specialiștii noștri sau de angajații noștri. Vă puteți familiariza cu tarifele pe pagina SMS-tarife.

  • Garantie de livrare prin SMS, banii se retrag doar pentru SMS-urile livrate.
  • Facturare separată pentru fiecare SMS.
  • Refacerea echilibrului în diferite moduri.
  • Vizualizați oricând istoricul tuturor SMS-urilor trimise.
  • Numele expeditorului în loc de numărul numeric de pe telefonul destinatarului.
Acest articol se bazează pe întrebări de pe forumuri: „Cum returnez un șir de caractere dintr-un DLL?”, „Cum transmit și returnez o matrice de înregistrări?”, „Cum transmit un formular unui DLL?”.

Ca să nu-ți petreci jumătate din viață să-ți dai seama - în acest articol voi aduce totul pe un platou de argint.

Subiectele acestui articol, în grade diferite, au fost deja atinse de mai multe ori în acest blog, dar în acest articol sunt adunate la grămadă, sunt date justificări. Pe scurt, un link către acest articol poate fi aruncat celor care dezvoltă DLL.

Notă importantă: articolul trebuie citit rand pe rand. Exemplele de cod sunt furnizate numai ca exemple, la fiecare pas (punct) al articolului se adauga codul de exemple cu detalii noi. De exemplu, chiar la începutul articolului nu există o gestionare a erorilor, sunt indicate metode „clasice” (cum ar fi folosirea GetLastError , convențiile sdtcall etc.), care sunt înlocuite cu altele mai adecvate în cursul articolului. Acest lucru se face din motivul că modelele „noi” („neobișnuite”) nu ridică întrebări. În caz contrar, la fiecare exemplu, ar trebui să se insereze o notă de forma: „asta se discută în acel paragraf de mai jos, dar că – în acesta aici”. În orice caz, la sfârșitul articolului există un link către un cod gata făcut, scris ținând cont de tot ce se spune în articol. Poți doar să-l iei și să-l folosești. Și articolul explică de ce și de ce. Dacă nu sunteți interesat de „de ce și de ce” - derulați până la sfârșit până la concluzie și un link pentru a descărca exemplul.

Top articole similare