Delphi – Kompetenzerkundung:
{Nr. 1}
Sätze zur Bildung modaler Formen:
Klasse PROcedure TMyForm.RunForm(AObj1, AObj2: TObject);
var
vForm: TMyForm;
beginnen
vForm := TMyForm.Create(application);
mit vForm tun
Versuchen
InitForm(AObj1, AObj2);
ShowModal;
Endlich
Frei;
Ende;
Ende;
//*veranschaulichen:
Durch die Klasse deklarierte Funktionen ähneln statischen Funktionen in VC; use-Anweisung: TMyForm.RunForm(vObj1, vObj2);
Weitere spezifische Informationen finden Sie unter: Klassenbeschreibung in der Delphi-Hilfe.
Der Zweck der Betonung dieses Idioms besteht darin:
1. Wenn dieses Formular an mehreren Stellen verwendet wird, können Sie sicherstellen, dass dieser Code einheitlich aufgerufen wird.
2. Wenn die Funktion geändert wird, zum Beispiel: Verarbeitung basierend auf dem Rückgabewert von ShowModal, dann ändern Sie nur diese Funktion.
3. Das Programm verfügt über eine gute Kapselung und ist einfach zu warten und zu übergeben. *//
{Nr. 2}//Verwendung des Tags
Reaktion auf Schaltflächenereignisse in der Formularsymbolleiste
procedure TMyForm.RunOperate(ATag: Integer);
beginnen
Fall ATag von
1: MyButton.Color := clRed;
2: MyButton.Color := clGreen;
3: MyButton.Color := clBlack;
Ende;
Ende;
procedure TMyForm.ToolBtnClick(Sender: TObject);
beginnen
RunOperate(TControl(Sender).Tag);
Ende;
Wenn Sie sich in einem Dropdown-Menü befinden und ähnliche Funktionen ausführen müssen,
procedure TMyForm.MenuItemClick(Sender: TObject);
beginnen
RunOperate(TMenuItem(Sender).Tag);
Ende;
//*veranschaulichen:
1. Klare Struktur
2. Relevante Informationen werden gebündelt, sodass sie leichter überprüft, geändert und verwaltet werden können.
3. Verbessern Sie die Anpassungsfähigkeit und Skalierbarkeit des Programms. Wenn die Anforderung beispielsweise nicht in der Symbolleistenschaltfläche, sondern in anderen Schaltflächen implementiert ist, kann sie leicht geändert werden.
Vorschlag: Auf jede Kategorie folgen nur eine oder einige Codezeilen. Wenn viel Code vorhanden ist, verwenden Sie stattdessen eine Prozessfunktion.
Interessanter ist, dass ich oft wie folgt schreibe:
Fall btnMyButton.Visible von
{show} Stimmt: ...
{Nicht anzeigen} Falsch: ...
Ende; *//
{ Nr. 3 }//Ereigniszeiger als Parameter
//Verwenden Sie den Ereigniszeiger für Leselisten usw.
Typ
TDataSetEvent = procedure (DataSet: TDataSet; AIndex, ACount: Integer) of Object;
//Von TADOQuery abgeleitete Klassen
procedure TMyADOQuery.EnumRecord(AWhereStr: String; APro: TDataSetEvent);
beginnen
Schließen;
SQL.Clear;
SQL.Add('Select * From Table1');
if AWhereStr <> '' dann
SQL.Add('Where ' + AWhereStr);
Offen;
Während nicht Eof Do
beginnen
if Assigned(APro) then APro(Self, RecNo, RecordCount);
Nächste;
Ende;
Schließen;
Ende;
//*veranschaulichen:
Diese Methode stammt von der API-Funktion in Window zum Aufzählen aller aktuellen untergeordneten Fenster, EnumChildWindow
1. Prinzip: Versuchen Sie, das Lesen von Daten von der Datenanzeige, Datenverarbeitung usw. zu trennen; MVC usw. dienen alle diesem Zweck.
2. Die Skalierbarkeit des Programms wurde verbessert. Wenn Sie ursprünglich eine bestimmte Informationsspalte in einer Liste anzeigen oder verarbeiten wollten, aber später zur Verwendung von ComboBox wechselten, müssen Sie beim Ändern des Programms den Datenleseteil nicht lesen , Sie müssen nur die Informationsanzeige usw. ändern. Als weiteres Beispiel müssen Sie nun einen Fortschrittsbalken verwenden, um den Lesefortschritt beim Lesen von Datensätzen anzuzeigen.
*//
{ Nr. 4 } //Konstantes Array
{In Nr.2 werden folgende Inhalte umgesetzt
procedure TMyForm.RunOperate(ATag: Integer);
beginnen
Fall ATag von
1: MyButton.Color := clRed;
2: MyButton.Color := clGreen;
3: MyButton.Color := clBlack;
Ende;
Ende;
}
//Dann wäre es ideal, es über ein Array zu implementieren.
procedure TMyForm.RunOperate(ATag: Integer);
const
MyButtonColorMax := 3;
MyButtonColor: Array [1..MyButtonColorMax] von TColor = (clRed, clGreen, clBlack);
beginnen
Fall ATag von
1..MyButtonColorMax: MyButton.Color := MyButtonColor[ATag];
101:....
Ende;
Ende;
//*veranschaulichen:
Beachten Sie bei der Verwendung im Array-Modus lediglich, dass die Ober- oder Untergrenze des Arrays mithilfe von Konstanten implementiert wird, und versuchen Sie dann, diese Konstante in zukünftigen Verwendungen zum Lesen von Array-Schleifen zu verwenden.
*//
{Nr. 5}Der Nachrichtenmechanismus reduziert die öffentlichen Funktionen der Klasse
//So minimieren Sie die Definition öffentlicher Funktionen in einem Formular;
{Zum Beispiel: Wenn Sie ein Eigenschaftslistenformular des aktuellen Formularsteuerelements implementieren möchten, müssen Sie den Wert einer bestimmten Eigenschaft usw. ändern mit dem interagiert werden muss. Wenn wir öffentliche Klassenfunktionen verwenden, müssen wir viele öffentliche Funktionen definieren. Wenn gleichzeitig eine Formulartypkonvertierung erforderlich ist, können öffentliche Funktionen erst nach der Konvertierung in den Zielformulartyp verwendet werden. Daher wird es Situationen geben, in denen zwei Einheiten einander einbeziehen müssen}
//Lösung:
TfrmMyForm = class(TForm)
FfrmProperty: TForm;
Ende;
...
FfrmProperty := TfrmProperty.MyCreate(Application, Self);
...
//Wenn das Eigenschaftenfenster aktualisiert werden muss
FfrmProperty.Perform(WD_REFRESHPROPERTYLIST, 0, 0);
TfrmProperty = class(TForm)
Privat
FMyForm: TForm;
procedure WDREFRESHPROPERTYLIST(var Message: TMessage); message WD_REFRESHPROPERTYLIST;
öffentlich
Konstruktor MyCreate(Owner: TComponent; AForm: TForm);
Ende;
Konstruktor TfrmProperty.MyCreate(Owner: TComponent; AForm: TForm);
beginnen
geerbt Create(Owner);
FMyForm := AForm;
Ende;
//* Für die Art und Weise der Verwendung von Nachrichten kann die Definition öffentlicher Funktionen des Formulars reduziert werden. Gleichzeitig verbessert es die Skalierbarkeit des Programms. Wenn Sie stattdessen sein Formular verwenden, kann es problemlos konvertiert werden, da es höchstens Ihr Formular ist und die aktuelle Nachricht nicht verarbeitet*)//
{Nr. 6}Verwenden Sie die Registrierungsliste, um mögliche Erweiterungsmodule zu verwalten
//Projekt: Sie müssen mehrere Ausgabeanzeigemethoden für einen Datensatz unterstützen
...Beispiele folgen später
//* veranschaulichen:
1. „Mehrere Ausgabemethoden“ bedeutet, dass die Ausgabemethoden in zukünftigen Anwendungen häufig erweitert werden können, sodass die einfache Skalierbarkeit der Ausgabemethoden beim Programmentwurf berücksichtigt werden muss.
2. In Bezug auf den Steuerelementregistrierungsmechanismus (RegisterComponents) in VCL können Sie feststellen, dass in VCL eine große Anzahl von Registrierungsmechanismen verwendet wird. Der klassischere ist die Registrierung des Steuerelementeigenschafteneditors.
*//
{Nr.7}Vordefinierte Steuerungsprogrammversion verwenden
// Wenn Sie ein sekundäres Entwicklungsplattformprogramm durchführen, müssen Sie Probleme mit der Produktversionskontrolle und der Projektversionskontrolle haben
//Wird normalerweise mit vordefinierten Methoden gesteuert
//Die Aussage ist relativ einfach:
{$DEFINE JOYYUAN97}
{$IFDEF JOYYUAN97} {ELSE} {ENDIF}
{$UNDEF JOYYUAN97}
*veranschaulichen:
1. Teilen Sie die Vordefinition in mehrere separate Dateien auf.
2. Verwenden Sie am Anfang jeder Einheit, aber nach der Einheit, {$I ...}, um die Datei in die aktuelle Einheit einzubinden.
3. Steuern Sie die Unit-Dateien, die die aktuelle Unit enthalten kann, basierend auf vordefinierten Bedingungen
4. Versuchen Sie, eine vordefinierte Datei für das Projekt zu trennen. Fügen Sie diese Datei entsprechend den Anforderungen des Projekts ein.
*//
{Nr. 8}Verwenden Sie Funktionszeiger, um die Einbindung von Unit-Projekten zu reduzieren
//Ich denke oft, dass die Reduzierung der Einbeziehung von Einheiten der erste Schritt zur Schaffung öffentlicher Einheiten ist, also wie man die Einbeziehung von Einheiten so weit wie möglich reduzieren kann
//Das heißt, es sollten mehr Anstrengungen unternommen werden, um die Kopplung von Programmeinheiten zu reduzieren.
{Szenariobeschreibung:
TMyFormManager: Formularverwaltungsklasse
TMyForm: Basisklasse für Datenformulare
TMyFormaccess: Klasse zum Speichern und Lesen von Formularinformationen. Speichern Sie die Formularinformationen in einer Datenbank oder einer anderen Art von Struktur
analysieren:
1. Die Formularbasisklasse (TMyForm) und die Formularverwaltungsklasse (TMyFormManager) müssen in einer Einheit uManagers implementiert werden.
2. Die formularspezifische Implementierungsklasseneinheit (TMyImageForm) fMyImange muss die Einheit uManagers für die Formularvererbung und Formularverwaltung enthalten.
3. Die Einheit uMyAccess der Klasse zum Lesen von Formulardaten (TMyFormAccess) muss die Einheit uManagers und die Einheit fMyImange enthalten
Frage:
Wenn ich das Formular speichern möchte, sollte dies in einem Schaltflächenereignis des Formulars erfolgen. Wenn es um die Formulareinheit geht, muss sie die Formulardatenzugriffsklasseneinheit enthalten, und wenn sie in der Formularbasisklasse platziert wird, muss die Einheit uManager die Einheit uMyAccess enthalten.
Der Einschluss von Zellen stellt eine Gefahr dar, wenn sich der Datenzugriff, d. h. Datenspeicherformate, je nach Anforderungen ändern und Skalierbarkeit erfordern.
Lösung: Funktionszeigervariablen verwenden.
1. Definieren Sie eine Funktionszeigervariable in der Unit uManagers, um Dateninformationen zu speichern.
2. Weisen Sie dieser Funktionszeigervariablen einen Wert zu, wenn die Anwendung initialisiert wird.
3. Wenn die Formularinformationen gespeichert werden müssen, stellen Sie fest, ob der Zeiger nicht leer ist, und führen Sie dann die Funktion zum Speichern der Formularinformationen aus.
{Nr. 9}Konstanten, Konstanten verstehen, Konstanten verwenden
Es gibt viele Bücher, in denen die Bedeutung der Konstantendefinition erläutert wird, und ich denke oft darüber nach, aber wenn ich mir den VCL-Quellcode ansehe, wird mir klar, dass ich die Verwendung von Konstanten durch andere ignoriert habe.
1. Die Definition einer Nachricht, die wir häufig verwenden, lautet: Deklarieren Sie eine Konstante und verwenden Sie sie dann zum richtigen Zeitpunkt.
Allgemein definiert und verwendet:
const
WD_MyMessage = WM_User + 101;
Typ
TMyForm = class(TForm)
...
procedure WDMyMessage(var message: TMessage); message WD_MyMessage; {response message position}
Ende;
Wenn Sie die Anweisung {response message position} jedoch wie folgt umschreiben:
procedure WDMyMessage(var message: TMessage); message WM_User + 101;
Ebenso kann die Kompilierung erfolgreich sein und die Verwendung ist normal. Daher werden Konstantendefinitionen sehr häufig in der Windows-Systemverarbeitung und in Schnittstellen verwendet.
2. In Delphi haben wir Farbvariablen clRed, clGreen usw. definiert, die auch definierte Konstanten sind, um die zukünftige Verwendung zu erleichtern. Durch diese Beobachtung habe ich herausgefunden, dass die Definition von Konstanten im Projekt teilweise wiederverwendbar sein sollte. Daher kann eine Standardkonstanteneinheit definiert werden, sodass die definierten Konstanten in jedem Projekt wiederverwendet werden können.
{Nr. 10}Ein häufig verwendetes Array in Delphi
Für die Definition und Verwendung von Arrays vom Typ TIdentMapEntryd gibt es in Delphi eine relativ vollständige Implementierung.
TIdentMapEntry = Datensatz
Wert: Ganzzahl;
Name: Zeichenfolge;
Ende;
1. Array-Definition: array[0..ArrMax] von TIdentMapEntry
Siehe: Steuereinheit:
Cursor: Array[0..21] von TIdentMapEntry = (
...
);
2. Zwei Funktionen, die sich gegenseitig auswerten: IntToIdent (Name aus Wert finden) und IdentToInt (Wert aus Name finden);
Spezifische Anwendungen finden Sie unter: IdentToCursor und CursorToIdent.
3. Anwendung: a. Wenden Sie diese Baumgruppendefinitionsmethode und Array-Manipulationsfunktion direkt an. b. Erfahren Sie, wie Sie auf Arrays in der Funktion zugreifen. c. Lernen Sie die Standarddefinition der Informationszugriffsfunktion kennen: function IntToIdent(Int: Longint; var Ident: string; const Map: array of TIdentMapEntry): Boolean; Ob der Zugriff gültig ist, wird zurückgegeben wird durch die Funktion geleitet Der boolesche Rückgabewert wird beurteilt.
{Nr. 11}Von Sonderfällen bis hin zu alltäglichen Entdeckungen
Durch die Verfolgung der Definitions- und Betriebsfunktionen von Cursorn habe ich Folgendes herausgefunden:
1. Wie in {Nr. 10} eingeführt, verallgemeinern Sie die Definition und die allgemeinen Operationen von Cursorn.
2. Stellen Sie Funktionen zur Konvertierung zwischen Int und Ident bereit.
3. Bietet eine Funktion zum zyklischen Lesen von Array-Listeninformationen: Unter anderem wird die in {Nr. 3} eingeführte Methode „Ereigniszeiger als Parameter“ zum Lesen von Listeninformationen verwendet.
Ergänzung zu {Nr. 6}:
Beispiel:
procedure RegisterComponents(const Page: string;
ComponentClasses: Array von TComponentClass);
beginnen
wenn Assigned(RegisterComponentsProc) dann
RegisterComponentsProc(Seite, ComponentClasses)
anders
raise EComponentError.CreateRes(@SRegisterError);
Ende;
Interpretation:
1. Verwenden Sie die Registrierungsmethode, um die Arten von Steuerelementen aufzuzeichnen, die verwendet werden können usw.
3. Für RegisterComponentsProc wird die Methode „Verwendung von Funktionszeigern zur Reduzierung der Einbindung von Unit-Projekten“ in {Nr. 8} verwendet, um zukünftige Programmerweiterungen, Versions-Upgrades usw. zu erleichtern.
{Nr. 11}Definieren Sie nur eine öffentliche Funktion
//Projektbeschreibung: Jetzt müssen wir ein CAD-Zeichnungs- oder Visio-System implementieren, das eine gute Skalierbarkeit und einfache Wartung erfordert;
//Und es erfordert eine geringe Kopplung, damit Teile des Systems oder des erweiterten Systems verpackt und direkt in zukünftigen Projekten verwendet werden können.
Design:
1. Entwerfen Sie in dieser Klasse eine abstrakte Funktion CadPerform. Die Parameter der Funktion beziehen sich auf die Funktion TControl.Perform(Msg: Cardinal; WParam, LParam: Longint).
2. Implementieren Sie in der Grafikverwaltungsklasse die Verwaltung einer Grafikobjektliste. In der Liste wird der Zeiger des abstrakten Objekts gespeichert.
3. Wenn Sie bestimmte Klassenobjekte steuern möchten, müssen Sie nur die CanPerform-Funktion verwenden und dann Msg entsprechend der Kategorie des aktuellen Vorgangs und die entsprechenden Parameterinformationen übergeben.
Implementierung: TCad ist die von der abstrakten Klasse geerbte Kontrollklasse der ersten Ebene
function TCad.CadPerform(Msg: Cardinal; WParam, LParam: Longint): Longint;
beginnen
Fallnachricht von
My_Message1: Ergebnis := MyMessage1(WParam, LParam);
My_Message2: Ergebnis := MyMessage2(WParam, LParam);
Ende;
Ende;
Da TPoint von TCad erbt, wird die CadPerform-Funktion wie folgt implementiert.
function TPoint.CadPerform(Msg: Cardinal; WParam, LParam: Longint): Longint;
beginnen
Fallnachricht von
My_Message1: Ergebnis := MyMessage1(WParam, LParam); //Die Verarbeitung dieses Operationstyps in TCad ist blockiert
My_Message3: Ergebnis := MyMessage3(WParam, LParam);
else Ergebnis := inherited CadPerform(Msg, WParam, LParam);
Ende;
Ende;
*veranschaulichen:
Da wir Grafikobjekte sehr häufig bedienen, definieren wir eine öffentliche und offene Schnittstellenfunktion, um eine hohe Kapselung der Klasse und eine einfache Wartung und Erweiterung des Programms zu erreichen.
*//
{Nr. 12}
Im Folgenden sind meine Programmieranforderungen aufgeführt: (Einige Informationen unterliegen keinen Sprachbeschränkungen)
//Fast alle der folgenden Lösungen sind in den oben genannten Methoden zu finden.
1. Reduzieren Sie die Komplexität des Programms. a. Reduzieren Sie die Anzahl der Funktionen, verwenden Sie Case- und Tag-Methoden und lernen Sie, wie Sie die Verschachtelungsbeziehungen von Einheiten reduzieren, Methoden zur Nachrichtenübermittlung verwenden und die gegenseitige Einbeziehung von Formulareinheiten reduzieren.
2. Reduzieren
{Nr. 13} Verwenden Sie Broadcasting, um Benachrichtigungen von Verwaltungsklassen an Verwaltungslistenobjekte zu implementieren
//Für die Projektbeschreibung {Nr. 12} ist es häufig erforderlich, alle Grafikobjekte zu benachrichtigen und entsprechende Änderungen vorzunehmen, wenn sich die Eigenschaften oder der Status der Zeichnungsformularsteuerung ändern.
// Wenn nur eine Broadcast-Funktion definiert ist, kann eine Eltern-Kind-Benachrichtigung realisiert werden, was auch die Wiederverwendbarkeit, Skalierbarkeit, Wartungsfreundlichkeit usw. des Programms verbessert und die Klassenstruktur klarer macht.
//Zum Beispiel: 1. Wenn sich in Visio und MapInfo der Maßstab (Zoomverhältnis) des aktuellen Formulars ändert, müssen alle aktuell angezeigten Grafikobjekte mit dem neuen Maßstab neu gezeichnet werden. 2. Wenn die Standard-Formularschriftart des aktuellen Formulars geändert wird, sollten auch die Textschriftarten von Grafikobjekten, die standardmäßig die Formularschriftart zum Anzeigen von Textinformationen verwenden, entsprechend geändert werden.
//Lösung, beziehen Sie sich auf den Verarbeitungsmechanismus in TWinControl, der alle Untersteuerelemente benachrichtigt, wenn sich Attribute oder Status ändern:
procedure TWinControl.NotifyControls(Msg: Word);
var
Nachricht: TMessage;
beginnen
Message.Msg := Msg;
Message.WParam := 0;
Message.LParam := 0;
Message.Result := 0;
Broadcast(Message);//Broadcast die aktuelle Änderungsnachricht
Ende;
In:
procedure TWinControl.Broadcast(var Message);
var
I: Ganzzahl;
beginnen
for I := 0 to ControlCount - 1 do
beginnen
Controls[I].WindowProc(TMessage(Message));
//Ändern zu: with TMessage(Message) do Cads[I].CadPerform(msg, WParam, LParam);
wenn TMessage(Message).Result <> 0 dann Exit;
Ende;
Ende;
Wenn wir jedoch mit Grafikobjekten arbeiten, können wir die öffentliche Funktion CanPerform von Cads direkt aufrufen.
{Nr. 14}Erstellen Sie Ihre Objekte bei Bedarf dynamisch
Zum Beispiel: http://www.delphibbs.com/keylife/iblog_show.asp?xid=824
//***************Option 2: Erstellen Sie bei Bedarf ein Eigenschaftsformular
verwendet
...
fEigenschaft;
Typ
TfrmMyMap = Klasse
...
procedure OnfrmMyMapDestroy(Sender: TObject);
procedure OnMapGeoSelected(AGeo: TGeometry);
Privat
FfrmProperty: TfrmProperty;
procedure ShowPropertyForm(aVisible: Boolean);
öffentlich
Ende;
procedure TfrmMyMap.ShowPropertyForm(aVisible: Boolean);
beginnen
if Not Assigned(FfrmProperty) then FfrmProperty := TfrmProperty.Create(Application);
FfrmProperty.Visible := aVisible;
Ende;
procedure TfrmMyMap.OnfrmMyMapDestroy(Sender: TObject);
beginnen
if Assigned(FfrmProperty) then FfrmProperty.Free;
Ende;
procedure TfrmMyMap.OnMapGeoSelected(AGeo: TGeometry);
beginnen
if Assigned(FfrmProperty) then FfrmProperty.MyRefresh(AGeo);
Ende;
Hier wird es erklärt:
1. Erstellen Sie Ihr Objekt FfrmProperty bei Bedarf dynamisch
2. Wenn das aktuelle Objekt freigegeben wird, bestimmen Sie die Rechtmäßigkeit Ihres Objekts und geben Sie dann das dynamisch erstellte Objekt frei.
{Nr. 15}Erstellen Sie eine Schnittstelle oder erstellen Sie eine Struktur
// Projektbeschreibung: Wenn ich ein Tabellensteuerelement entwickle und die Zelle auf „Com“ setze und die Tabelle zu viele Informationen enthält, kann die Ladegeschwindigkeit nicht garantiert werden und es besteht sogar die Möglichkeit eines Absturzes. Der Grund, warum ich Com verwende, besteht darin, dass die Verarbeitung und Information jeder Zelle in Zukunft außerhalb der Kontrolle erweitert werden kann.
Meine Lösung ist: Erstellen Sie eine Instanz für jedes von der Zelle abgeleitete Steuerelement und erstellen Sie dynamisch mehrere Strukturobjekte. Aufzeichnen, um die Informationen jeder Zelle aufzuzeichnen. Wenn Sie die Zelle bedienen müssen, weisen Sie den Strukturobjektzeiger der Zellkomponente zu. Die Testergebnisse sind sehr zufriedenstellend.
Wenn Sie daher eine große Anzahl von Instanzen eines Com verwenden müssen, versuchen Sie, eine Instanz zu verwalten und zu warten. Die darin enthaltenen Daten können dann dynamisch erstellt und verwaltet werden, was sich positiv auf die Geschwindigkeit auswirkt.
Versuchen Sie außerdem, einen Schnittstellenzeiger pMyInterface = ^IMyInterface zu deklarieren, indem Sie den Schnittstellenzeiger direkt verwenden. Dies kann die Anzahl der Aufrufe der Zählfunktion _AddInft usw. verringern und auch die Geschwindigkeit erhöhen Die Bedienung ist normal.