Geben Sie Ihrem Kunden die Kontrolle über die gui
Dieser Artikel beschreibt, wie Benutzer ihre GUI zur Laufzeit ändern können.
| Delphi-Entwickler | Februar 1999 |
Copyright Pinnacle Publishing, Inc. Alle Rechte vorbehalten.
Geben Sie Ihren Kunden-Kontrolle über die GUISteve Zimmelman
Wie oft haben Sie geliefert, was Sie dachte, war eine fertige Anwendung, nur zu hören Ihre Kunden sagen, 'Gee, dieses ist nett, aber ich möchte wirklich den Namen auf der linken Seite, und das Feld Status sollte rot, nicht schwarz, und...' Wäre es nicht schön, wenn alles, was Ihre Nutzer zu tun hatte war der rechten Maustaste auf das Steuerelement, und kommt ein Popup-Menü, so dass sie die Attribute des Steuerelements ändern? Oder drücken sie STRG-ArrowKey oder Shift-ArrowKey um die Position oder Größe des Steuerelements ändern?Denn Benutzer Kontrolle über die GUI ist ein zweistufiger Prozess. Zuerst müssen Sie Steuerelemente mit Eigenschaften zu erstellen, die Benutzer zur Laufzeit ändern können, und dann muss man eine Möglichkeit zum Speichern und Wiederherstellen von Änderungen. Normalerweise ist das Steuerelement, das den meisten Einsatz Ruft die DBEdit. So werden in diesem Beispiel auf konzentrieren verwendet zum Erstellen einer DBEdit, eine angepasste PopupMenu, die aktiviert wird auf der rechten Maustaste auf die Maus. Das Menü ermöglicht es den Benutzer, Text Fall Farbe, Schriftart und Tab-Reihenfolge ändern. Darüber hinaus ändert die Tastenkombination STRG-Taste und Shift-Taste die Position und Größe des Steuerelements, bzw..
Bevor ich beginne, möchte ich Sie auf eine neue Eigenschaft Text-Fall vorstellen: ProperCase. Die meisten richtigen-Koffer Konvertierungen nutzen in der Regel nur den ersten Buchstaben, dann einen beliebigen Buchstaben, die ein Leerzeichen folgt. Aber dadurch, dass eine Vielzahl von Namen und abgekürzten Titel suchen ein wenig umständlich, wie McDonald, O'Hara, M.D., und so weiter. Also in meinem Versuch, eine bessere Mausefalle zu erstellen, ich eine richtige-Koffer Konvertierung, die die Intelligenz enthalten, diese besonderen Namen zu behandeln hat. Ich stellte die Funktionen, die für die ordnungsgemäße-Koffer Umwandlung in eine Einheit namens StrFunc.pas verwendet und dann das Gerät StrFunc in den Bedeutungen der Komponente einbezogen.
Erstellen der veränderlichen DBEditDas erste, was, das ich tat, war eine neue Komponente mit TDBEdit als die übergeordnete Klasse zu erstellen. Ich rief die neue Klasse TPSIDBEdit, weil der Name des Unternehmens arbeite ich für PSI ist, und es war eine einfache Möglichkeit, um die Komponente zu unterscheiden. Als nächstes habe ich eine neuartige CharCase, die ProperCase enthält. Es wird verwendet, die DBEdit TCharCase zu überschreiben. Ich habe auch die CharCase-Eigenschaft auf eine neue Art, TPSICharCase. Neben die CharCase-Eigenschaft überschreiben, führte ich zwei neue Eigenschaften: AllowUserChange und PopupChangeMenu. Die AllowUserChange-Eigenschaft ist eine einfache boolesche Schalter, der engagiert oder trennt die Fähigkeit der Benutzer die Eigenschaften der Komponente zur Laufzeit ändern, und PopupChangeMenu ist ein Zeiger auf das PopupMenu, die wirksam ist, wenn AllowUserChange auf True festgelegt ist. Ein Großteil der Komponente ändern geschieht eigentlich durch die PopupChangeMenu, aber wird erläutert, die ein wenig später. Codebeispiel 1 präsentiert die PSIDBEdit Einheit.
Codebeispiel 1. Die PSIDBEdit-Einheit.
Einheit PSIDBEdit;
Schnittstelle
verwendet
Windows, SysUtils, Klassen, Steuerelemente, Formulare, Dialoge,
DBCtrls, Menüs, Db, StrFunc;
Typ
TPSICharCase = (EcNormal, EcUpperCase,
EcLowerCase, EcProperCase);
TPSIDBEdit = class(TDBEdit)
Private
fCharCase: TPSICharCase;
fIsChanging: Boolean;
fAllowUserChange: Boolean;
fStartMove: Boolean;
fTop: Integer;
fLeft: Integer;
fChangeMenu: TpopupMenu;
fPopupSave: TPopupMenu;
Prozedur SetAllowUserChange(Value:Boolean);
Prozedur SetChangeMenu(Value:TpopupMenu);
Prozedur SetPopUpMenu;
Prozedur SetCharCase(Value:TPSICharCase);
Procedure SetTextCase (Const bCheckState:Boolean);
geschützt
öffentliche
Verfahren geladen; Außer Kraft setzen;
Änderung der Verfahren; Außer Kraft setzen;
Verfahren KeyDown (Var Key: Word;
Verschiebung: TShiftState); außer Kraft setzen;
Verfahren MouseDown (Schaltfläche: TMouseButton; Verschiebung:
TShiftState; X, Y: Integer);
Außer Kraft setzen;
MouseMove-Prozedur (Shift: TShiftState;
X, Y: Integer); Außer Kraft setzen;
MouseUp-Prozedur (Schaltfläche: TMouseButton; Verschiebung:
TShiftState; X, Y: Integer);
Außer Kraft setzen;
veröffentlicht
Eigenschaft AllowUserChange: Boolescher
FAllowUserChange lesen
Schreiben Sie SetAllowUserChange;
CharCase Eigenschaft: TPSICharCase
FCharCase lesen
Schreiben Sie SetCharCase;
Eigenschaft PopupChangeMenu: TPopupMenu
FChangeMenu lesen
Schreiben Sie SetChangeMenu;
Ende;
Ich wollte die Komponente, die zwei Zustände haben: eine Standard-Staat, der wie sein Vorgänger Verhalten würde, und ein Design-Zustand, die es erlauben den Benutzer, seine Eigenschaften zur Laufzeit ändern. Die boolesche Eigenschaft AllowUserChange unterscheidet zwischen diesen beiden Zuständen. Wenn AllowUserChange True ist, wird die Komponente PopupMenu geändert, um auf den Wert in der PopupChangeMenu-Eigenschaft gespeicherten verweisen. Wenn es falsch ist, wird die PopupMenu-Eigenschaft auf seine früheren Entwurf Zeit Zuordnung zurückgesetzt. Darüber hinaus können die Komponente verschoben oder verkleinert werden. Ich dachte, es wäre schön für den Benutzer in der Lage, einen Unterschied zwischen den beiden Staaten, so dass ich den Cursor in CrHandPoint (-21) in der SetAllowUserChange-Methode geändert werden.
Die PopupMenu-Zuordnung wird über die SetPopupMenu-Methode geändert, wenn die AllowUserChange-Eigenschaft geändert wird.
Um die PopupMenu-Zeiger zu tauschen, wird der Standardwert PopupMenu in fPopupSave in der geladenen-Methode (siehe Listing 2) gespeichert. Anschließend wird die SetPopupMenu-Methode aufgerufen, um sicherzustellen, dass das ordnungsgemäße Popup-Menü zugewiesen wird, basierend auf dem Wert des AllowUserChange.
Codebeispiel 2. Die geladenen Methode.
Prozedur TPSIDBEdit.Loaded;
BEGIN
Versuchen Sie
Wenn (CsDesigning in ComponentState) dann Ausfahrt;
PopupMenu Zuordnung zu erfassen
fPopupSave: = PopupMenu;
SetPopupMenu;
Schließlich
Loaded geerbt;
Ende;
Ende;
Mit dem Aufkommen der neuen Text Fall ProperCase und den neuen Typ TPSICharCase musste ich komplett überschreiben und implementieren Sie erneut alle anderen standardmäßigen Text-Fall Konvertierungen in der Change-Methode der Komponente (siehe Listing 3).
Codebeispiel 3. Der Change-Methode.
Prozedur TPSIDBEdit.Change;
Var
iSelStart: Integer;
BEGIN
Versuchen Sie
Wenn (CsDesigning in ComponentState)
Oder fIsChanging dann Ausfahrt;
Cursorposition zu erfassen
iSelStart: = SelStart;
SetTextCase(False);
Cursor-Position wiederherstellen
SelStart: = iSelStart;
Schließlich
Erbte;
Ende;
Ende;
Die tatsächliche Veränderung des Textes war ein wenig schwierig. Wenn Sie den Text programmgesteuert ändern, wenn das Objekt den Fokus besitzt, und das DataSet nicht bearbeiten oder-Modus, dann die Ausnahme einfügen 'Dataset nicht im Modus bearbeiten oder einfügen' werden generiert. Also bevor Sie den Text ändern, muss die Komponente DataSet.State verhört und gegebenenfalls geändert werden. Wir müssen auch potenzielle Multiuser Konflikte behandeln, die auftreten können. Der Parameter bCheckState wird verwendet, um festzustellen, ob die DataSet.State im Modus bearbeiten oder Einfügen platziert werden, bevor Sie den Text ändern muss. Wenn dies der Fall, muss die Methode auch die Änderungen veröffentlichen. Die Post-Methode wird aufgerufen, nur wenn der Arbeitsspeicher Variable bPost auf True festgelegt ist. Listing 4 zeigt, wo all das geschieht in der SetTextCase-Methode.
Codebeispiel 4. Die SetTextCase-Methode.
Verfahren TPSIDBEdit.SetTextCase(Const bCheckState:
Boolean);
Var
bPost: Boolean;
Funktion CanChange: Boolean;
BEGIN
Versuchen Sie
Wenn nicht dann anfangen bCheckState
Ergebnis: = True;
Ausfahrt;
Ende;
Wenn (DataSource <> Nil) dann beginnen
Wenn nicht (DataSource.DataSet.State
In [DsEdit, DsInsert]) dann beginnen
Wenn DataSource.DataSet.Active dann beginnen
DataSource.DataSet.Edit;
bPost: = True;
Ende;
Ende;
Ende;
Ergebnis: = True;
Außer
Ergebnis: = False;
Ende;
Ende;
BEGIN
Wenn die Textänderungen und dem DataSet
ist nicht in EditState, dann eine Ausnahme
wird generiert. Stellen Sie sicher, dass DataSet ist
in EditState vor dem Ändern von Text.
fIsChanging: = True;
Versuchen Sie
bPost: = False;
Wenn CanChange dann beginnen
RS CharCase der
EcNormal: {Do Nothing};
EcUpperCase: Text: = UpperCase(Text);
EcLowerCase: Text: = LowerCase(Text);
EcProperCase: Text: = ToProper(Text);
Ende;
Wenn dann bPost
DataSource.DataSet.Post;
Anderes Ende
MessageDlg (' ein anderer Benutzer verwenden möglicherweise dies ' +
'Datensatz.' + #13 #13 +
' TextCase Änderungen möglicherweise nicht ' +
'sichtbaren für diesen Eintrag.',
mtWarning,[mbOK],0);
Schließlich
fIsChanging: = False;
Ende;
Ende;
Ändern der CharCase-Eigenschaft führt die SetCharCase-Methode (siehe Listing 5), die wiederum die SetTextCase-Methode ausgeführt wird.
Übersicht der 5. Die SetCharCase-Methode.
Prozedur TPSIDBEdit.SetCharCase(Value:TPSICharCase);
BEGIN
Dann beginnen Sie, wenn fCharCase <> Wert
fCharCase: = Value;
SetTextCase(True);
Ende;
Ende;
Damit das Steuerelement Bewegungsmöglichkeiten haben overrode ich das KeyDown-Verfahren (siehe Listing 6). Kreditaufnahme die Delphi IDE Tastatureingaben für Komponente verschieben und Ändern der Größe, habe ich die STRG-ArrowKeys für Bewegung und Shift-ArrowKeys für die Größenanpassung. Diese Tasten drücken, wird das Steuerelement seine Größe oder Position um ein Pixel zu ändern.
Inserat 6. Das KeyDown-Methode.
Procedure TPSIDBEdit.KeyDown (Var Key: Word;
Verschiebung: TShiftState);
BEGIN
Wenn (geben Sie [Vk_up, Vk_down, Vk_left Vk_right])
Und AllowUserChange Then Begin
Wenn (Shift = [SsCtrl]) dann beginnen
Position ändern
Case-Schlüssel von
Vk_Up: Top: = Top - 1;
Vk_Down: Top: = Top + 1;
Vk_Left: Links: = Left - 1;
Vk_Right: Links: = Links + 1;
Ende;
End Else If (Shift = [SsShift]) dann beginnen
Größe ändern
Case-Schlüssel von
Vk_Up: Höhe: = Höhe - 1;
Vk_Down: Höhe: = Höhe + 1;
Vk_Left: Breite: = Breite - 1;
Vk_Right: Breite: = Breite + 1;
Ende;
Ende;
Schlüssel: = 0;
End Else Begin
geerbte KeyDown(Key,Shift);
Ende;
Ende;
Ich wollte auch den Benutzer die Komponente mit der Maus verschieben, so dass ich die Methoden MouseDown, MouseUp und MouseMove overrode.
So weit, ist was du hast eine DBEdit, die einem Benutzer ermöglicht, seine Position und Größe, aber kaum etwas anderes ändern. Schriftart, Farbe, Tab-Reihenfolge, 3D-Effekt und Grenze erfolgt mit dem Zusatz der Komponente ChangeMenu.
Die Grundlage für diese Komponente ist in der Einheit TypInfo.pas, gefunden, die Sie auf ein Objekt RTTI (Laufzeit-Typinformationen) zugreifen können. TypInfo.pas enthält Funktionen und Prozeduren, die abrufen oder eine Objekt-Eigenschaftenwerte während der Ausführung der Anwendung festlegen können. Einige einfachen Methoden festlegen oder Abrufen Eigenschaftenwert eines Objekts zur Laufzeit können wie Listing 7 aussehen.
Übersicht der 7. Abrufen und Festlegen von-Eigenschaft eines Objekts zur Laufzeit.
Funktion GetProperty(Sender:TComponent
sPropName:String): Variante
Var
PropInfo: PPropinfo;
BEGIN
Erhalten Sie aus den Klasseninformationen die Eigenschaft
PropInfo: = GetPropInfo (Sender.ClassInfo,
sPropName);
Existiert die Eigenschaft?
Wenn (PropInfo <> Nil) dann beginnen
Rs. Propinfo ^. PropType ^. Eine Art
TkEnumeration, TkInteger:
BEGIN
Ergebnis: = GetOrdProp(Sender,PropInfo)
Ende;
TkString, TkLString, TkWString:
BEGIN
Ergebnis: = GetStrProp(Sender,PropInfo)
Ende;
Ende;
Anderes Ende
Ergebnis: = Null;
Ende;
Verfahren SetProperty(Sender:TComponent
; sPropName:String
vValue:Variant)
Var
PropInfo: PPropinfo;
BEGIN
Erhalten Sie aus den Klasseninformationen die Eigenschaft
PropInfo: = GetPropInfo (Sender.ClassInfo,
sPropName);
Existiert die Eigenschaft?
Wenn (PropInfo <> Nil) dann beginnen
Rs. Propinfo ^. PropType ^. Eine Art
TkEnumeration, TkInteger:
BEGIN
SetOrdProp(Sender,PropInfo,vValue);
Ende;
TkString, TkLString, TkWString:
BEGIN
SetStrProp(Sender,PropInfo,vValue);
Ende;
Ende;
Ende;
Ende;
Verwendung dieser beiden Methoden könnte wie folgt aussehen:
SetProperty(DBEdit1,'Ctl3D',False);
DBEdit2.Ctrl3D: = GetProperty(DBEdit1.'Ctl3D');
Zugegeben, können dieses Beispiel ist wahrscheinlich vereinfachenden, Verfahren wie diese jedoch ganz praktisch, wenn Sie nicht, den Komponentennamen, oder sogar seiner Klasse wissen.
Die drei wichtigsten Methoden in ChangeMenu--GetProperty(), SetProperty() und IsProperty()--verwendet werden in der Einheit PropFunc.pas gefunden, die Teil dieser Bibliothek ist. IsProperty() ist eine boolesche Funktion, die prüft, ob eine angegebene Eigenschaft in einem Objekt und gibt den Wert true, wenn die Eigenschaft vorhanden ist. Es kann sein etwas wie folgt verwendet:
Wenn dann die IsProperty(Form1.Components[i],'Ctl3D')
Komponenten [i]. Ctl3d: = False;
TChangeMenu ist eine Unterklasse des TPopupMenu mit zwei zusätzliche Eigenschaften: FontDialog und ColorDialog, die werden verwendet, um der Komponente Schriftart und Farbe ändern und können auf jede passende Klassentypen, die im Bereich der Komponente zeigen. Die Methoden MenuClick und OnMenuPopup den Großteil der Arbeit zu tun und sind die Ereignisse OnClick und OnPopup der Menüelemente zugewiesen, wenn die Komponente erstellt wird. All dies geschieht natürlich in der ChangeMenu-Einheit (siehe Codebeispiel 8).
Übersicht der 8. Die ChangeMenu-Einheit.
Einheit ChangeMenu;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Klassen, Grafiken,
Steuerelemente, Formulare, Dialogfelder, Menüs, Comctrls,
StdCtrls, Dbctrls, Db, Extctrls;
Typ
TChangeMenu = class(TPopupMenu)
Private
{Private Deklarationen}
Pm_Font: TMenuItem;
Pm_bgColor: TMenuItem;
Pm_TabOrder: TMenuItem;
pm_Ctrl3D: TMenuItem;
Pm_BorderStyle: TMenuItem;
Pm_Columns: TMenuItem;
Pm_Caption: TMenuItem;
pm_Divider1: TMenuItem;
Pm_UpperCase: TMenuItem;
Pm_LowerCase: TMenuItem;
Pm_MixedCase: TMenuItem;
Pm_ProperCase: TMenuItem;
Pm_Height: TMenuItem;
Pm_Width: TMenuItem;
Pm_Style: TMenuItem;
fFontDialog: TFontDialog;
fColorDialog: TColorDialog;
Prozedur SetColorDialog(Value:TColorDialog);
Prozedur SetFontDialog(Value:TFontDialog);
Prozedur MenuClick(Sender:TObject);
Prozedur OnMenuPopup(Sender:TObject);
geschützt
{Protected Deklarationen}
öffentliche
{Public Deklarationen}
Verfahren geladen; Außer Kraft setzen;
Destruktor zerstören; außer Kraft setzen;
Konstruktor Create(AOwner: TComponent); außer Kraft setzen;
veröffentlicht
{Veröffentlichten Erklärungen}
FontDialog Eigenschaft: TFontDialog
FFontDialog lesen
Schreiben Sie SetFontDialog;
ColorDialog Eigenschaft: TColorDialog
FColorDialog lesen
Schreiben Sie SetColorDialog;
Ende;
Register des Verfahrens;
Umsetzung
verwendet PropFunc, Col_edit;
Aufgrund der speziellen Einsatzbereich dieses Menüs werden die Menüelemente nur während der Laufzeit nicht zur Entwurfszeit in der IDE erstellt. Nachdem die Menüpunkte erstellt wurden, wird die Methode OnClick-Ereignis jedes Menüelement MenuClick() zugewiesen. Das Menü wird wie in Abbildung 1 aussehen.
Die geladene-Methode (siehe Listing 9) erfasst den Zeiger auf die Komponente OnPopup Methode, dann weist das OnPopup-Ereignis an die Methode OnMenuPoup(). Dies geschieht, damit der Entwickler OnPopup Methode ausgeführt wird, nachdem die OnMenuPopup-Methode eine eigene Menüelemente Verarbeitung beendet hat.
Codebeispiel 9. Die geladenen Methode.
Prozedur TChangeMenu.Loaded;
BEGIN
Versuchen Sie
Zeiger in der Komponente OnPopup Methode speichern
FOtherOnPopup: = OnPopup;
OnPopup-Methode zuweisen
OnPopup: = OnMenuPopup;
Schließlich
Erbte;
Ende;
Ende;
Wenn der Benutzer die Maus über die Komponente klickt, die OnMenuPopup Methode ist ausgeführt (siehe Listing 10) und initialisiert die Menüelemente basierend auf das Menü PopupComponent-Eigenschaft. PopupComponent ist ein Zeiger auf das Objekt, das Aktivieren des Menüs verantwortete und Typ TComponent. Beachten Sie die Verwendung der Methode IsProperty die sichtbare-Eigenschaft der Menüelemente festgelegt.
Liste der 10. Die OnMenuPopup-Methode.
Prozedur TChangeMenu.OnMenuPopup(Sender:TObject);
Initialisieren Sie Menüelemente auf der Grundlage der
konzentrierte sich Art und Eigenschaften der Komponente.
Var bSet: Boolean;
BEGIN
Keine Schriftart anzeigen Posten, wenn die Schriftart
Dialogfeld Eigenschaft ist Nil oder die Schriftart
Eigenschaft existiert nicht in der fokussierten
Komponente.
pm_Font.Visible: =
(Nicht (FontDialog = Nil))
Und IsProperty(PopupComponent,'Font');
Farbe zeigen nicht Posten, wenn die ColorDialog
Eigenschaft ist Nil oder die Color-Eigenschaft nicht
gibt es in der fokussierten Komponente.
pm_bgColor.Visible: =
Nicht (ColorDialog = Nil)
Und IsProperty(PopupComponent,'Color');
Initialisieren-Radio und aktivierten Menüpunkte
Wenn IsProperty (PopupComponent,
'BorderStyle') dann Begin
pm_BorderStyle.Checked: =
(GetProperty (PopupComponent,
'BorderStyle') = BsSingle);
pm_BorderStyle.Visible: = True;
End Else Begin
pm_BorderStyle.Visible: = False;
Ende;
Wenn IsProperty(PopupComponent,'Ctl3D') dann beginnen
pm_Ctrl3D.Checked: =
GetProperty(PopupComponent,'Ctl3D');
pm_Ctrl3D.Visible: = True;
End Else Begin
pm_Ctrl3D.Visible: = False;
Ende;
Wenn die Eigenschaft TabOrder in der Komponente vorhanden ist,
zeigen Sie das Menüelement 'Tab-Reihenfolge'.
pm_TabOrder.Visible:=
IsProperty(PopupComponent,'TabOrder');
Wenn die Columns-Eigenschaft in der Komponente vorhanden ist
und die Komponente ist TListView,
zeigen Sie das Menüelement.
If (PopupComponent TListView) dann
Pm_columns. Sichtbar: =
(IsProperty(PopupComponent,'Columns') und
(TListView(PopupComponent). Columns.Count > 0))
Sonst
Pm_columns. Sichtbar: = False;
Sie sollten nun die Idee haben...
pm_Caption.Visible: =
IsProperty(PopupComponent,'Caption');
Wenn die fokussierte Komponente verfügt über CharCase und
Eigenschaften der AllowUser ändern, dann verarbeiten mehr
Menüelemente.
Wenn (IsProperty(PopupComponent,'CharCase')
Und IsProperty (PopupComponent,
'AllowUserChange')) dann Begin
bSet: = True;
CharCase Elemente zeigen nicht wenn die
DataType nicht String.
Wenn IsProperty (PopupComponent,
'DataSource') dann Begin
If (PopupComponent TDBEdit) dann beginnen
Mit TDBEdit(PopupComponent) fangen
Wenn (DataField <> cm) dann beginnen
Wenn nicht (Field.DataType =
FtString) dann beginnen
bSet: = False;
Ende;
Anderes Ende
bSet: = False;
Ende;
Ende;
Ende;
pm_UpperCase.Visible: = bSet;
pm_LowerCase.Visible: = bSet;
pm_MixedCase.Visible: = bSet;
pm_ProperCase.Visible: = bSet;
pm_Divider1.Visible: = bSet;
CharCase Radio-Objekte zu initialisieren.
RS GetProperty(PopupComponent,'CharCase') der
ecNormal
0: pm_MixedCase.Checked: = True;
ecUpperCase
1: pm_UpperCase.Checked: = True;
ecLowerCase
2: pm_LowerCase.Checked: = True;
ecProperCase
3: pm_ProperCase.Checked: = True;
Ende;
End Else Begin
pm_UpperCase.Visible: = False;
pm_LowerCase.Visible: = False;
pm_MixedCase.Visible: = False;
pm_ProperCase.Visible: = False;
pm_Divider1.Visible: = False;
Ende;
pm_Width.Visible: = (PopupComponent ist TBevel);
pm_Height.Visible: = (PopupComponent ist TBevel);
pm_Style.Visible: = (PopupComponent ist TBevel);
Wenn pm_Style.Visible dann beginnen
Wenn GetProperty (PopupComponent, 'Stil') = 0 Then
pm_Style.Caption: = 'Bevel ausgelöst'
Sonst
pm_Style.Caption: = 'Senkte Abschrägung';
Ende;
Führen Sie OnPopup-Ereignis der Komponente.
Wenn Assigned(FOtherOnPopup) dann
FOtherOnPopup(Sender);
Ende;
Wenn ein Element wird aktiviert (siehe Codebeispiel 11) dient die Methode SetProperty() Eigenschaftenwerte des Objekts zu ändern.
Codebeispiel 11. Die MenuClick-Methode.
Prozedur TChangeMenu.MenuClick(Sender:TObject);
Prozess der Menü-Auswahl für die gezielte
Komponente.
Var
String: String;
i, iInt: Integer;
b: Boolean;
BEGIN
Wenn (TMenuItem(Sender) = pm_Ctrl3D) dann beginnen
Prozess-3D - 3D ausgewählt ist
dann muss die BorderStyle-Eigenschaft geändert werden
in Single.
b: = nicht Boolean (GetProperty (PopupComponent,
'Ctl3D'));
SetProperty(PopupComponent,'Ctl3D',Ord(b));
Wenn b und (GetProperty (PopupComponent,
'BorderStyle') = BsNone) dann
SetProperty (PopupComponent,
'BorderStyle', BsSingle);
Sonst endif (TMenuItem(Sender) =
Pm_BorderStyle) dann beginnen
Prozess-BorderStyle
Wenn (GetProperty (PopupComponent,
'BorderStyle') = BsSingle) dann beginnen
SetProperty (PopupComponent,
'BorderStyle', BsNone);
Wenn die BorderStyle-Eigenschaft auf None festgelegt ist
3D ausschalten.
SetProperty(PopupComponent,'Ctl3D',False);
Anderes Ende
SetProperty (PopupComponent,
'BorderStyle', BsSingle);
Sonst endif (TMenuItem(Sender) =
Pm_TabOrder) dann beginnen
Prozess-TabOrder
String: = IntToStr (GetProperty (PopupComponent,
'TabOrder'));
Versuchen Sie
String: = InputBox ('Set Aktivierreihenfolge',
'Geben Sie die Tab-Reihenfolge', String);
iInt: = StrToInt(sString);
SetProperty(PopupComponent,'TabOrder',iInt);
Außer
Exception.Create zu erhöhen ('Registerkarte Reihenfolge muss ' +
'Integer sein');
Ende;
End Else If (TMenuItem(Sender) = Pm_Font) dann beginnen
Auswahl von Schriftarten
Wenn (FontDialog-<>-Nil) dann beginnen
FontDialog.Font.Name: =
GetProperty(PopupComponent,'Font.Name');
FontDialog.Font.Size: =
GetProperty(PopupComponent,'Font.Size');
FontDialog.Font.Color: =
GetProperty(PopupComponent,'Font.Color');
FontDialog.Font.Style: =
TFontStyles (TFontStyle)
GetProperty(PopupComponent,'Font.Style')));
Wenn FontDialog.Execute dann beginnen
SetProperty (PopupComponent,'Font.Name '
FontDialog.Font.Name);
SetProperty (PopupComponent,'Font.Size ',
FontDialog.Font.Size);
SetProperty (PopupComponent,'Font.Color ',
FontDialog.Font.Color);
SetProperty (PopupComponent,'Font.Style ',
Ord(TFontStyle(FontDialog.Font.Style)));
Erzwingen Sie Schrifthöhe aktualisieren
die Komponente
i: = GetProperty(PopupComponent,
'Font.Height');
SetProperty (PopupComponent,
' Font.Height',i+(-5));
SetProperty (PopupComponent,
);
Ende;
Ende;
Sonst endif (TMenuItem(Sender) =
Pm_BgColor) dann beginnen
Prozessfarbe
Wenn dann ColorDialog <> Nil beginnen
ColorDialog.Color: =
GetProperty(PopupComponent,'Color');
Wenn ColorDialog.Execute dann beginnen
SetProperty (PopupComponent, 'Farbe',
ColorDialog.Color);
Ende;
Ende;
Sonst endif (TMenuItem(Sender) =
Pm_Caption) dann beginnen
Prozess-Beschriftung
String: = GetProperty(PopupComponent,'Caption');
String: = InputBox ('Beschriftung ändern',
'Geben Sie die Beschriftung', String);
SetProperty(PopupComponent,'Caption',sString);
Sonst endif (TMenuItem(Sender) =
& n SP; Pm_columns) dann beginnen
Prozess-Spalten für TListView. Dies geschieht
mit einer äußeren Form.
Application.CreateForm (TfrmEditColumns,
FrmEditColumns);
Versuchen Sie
frmEditColumns.ColObject: =
TListView(PopupComponent);
frmEditColumns.ShowModal;
Schließlich
frmEditColumns.Free;
Ende;
Anderes Ende wenn (TMenuItem(Sender)=pm_Width) dann beginnen
Prozess-Breite für TBevel
String: = IntToStr (GetProperty (PopupComponent,
'Breite'));
Versuchen Sie
String: = InputBox ('Breite festlegen',
'Geben Sie Breite', String);
iInt: = StrToInt(sString);
SetProperty(PopupComponent,'Width',iInt);
Außer
Exception.Create zu erhöhen ('Breite muß ' +
'Ein Integer');
Ende;
Anderes Ende wenn (TMenuItem(Sender)=pm_Height) dann beginnen
Prozess-Höhe für TBevel
String: = IntToStr (GetProperty (PopupComponent,
'Höhe'));
Versuchen Sie
String: = InputBox ('Höhe festlegen',
'Geben Sie die Höhe', String);
iInt: = StrToInt(sString);
SetProperty(PopupComponent,'Height',iInt);
Außer
Exception.Create erhöhen (' Höhe muß ' +
'Ein Integer');
Ende;
Anderes Ende wenn (TMenuItem(Sender)=pm_Style) dann beginnen
Prozess-Bevel-Stype für TBevel
Angehoben oder gesenkt
Wenn GetProperty (PopupComponent, 'Stil') = 0 Then
SetProperty(PopupComponent,'Style',1)
Sonst
SetProperty(PopupComponent,'Style',0)
End Else Begin
TMenuItem(Sender). Geprüft: =
Nicht TMenuItem(Sender). Geprüft;
Wenn pm_MixedCase.Checked dann beginnen
Normal
SetProperty(PopupComponent,'CharCase',0);
End Else If pm_UpperCase.Checked dann beginnen
CharCase: = EcUpperCase;
SetProperty(PopupComponent,'CharCase',1);
End Else If pm_LowerCase.Checked dann beginnen
CharCase: = EcLowerCase;
SetProperty(PopupComponent,'CharCase',2);
End Else If pm_ProperCase.Checked dann beginnen
CharCase: = EcProperCase;
SetProperty(PopupComponent,'CharCase',3);
Ende;
Ende;
Ende;
TChangeMenu kann eigentlich auf fast allen standard-Bauteil verwendet werden, die die unterstützten Eigenschaften hat. Es unterstützt sogar TListView Spaltenüberschriften und breiten.
Halb esErstellen einer Komponente, die dem Benutzer erlaubt, seine Größe, Position, Schriftart, Farbe und So weiter zu ändern, ist gut. Aber es ist nicht sehr hilfreich, ohne die Fähigkeit also speichern und Wiederherstellen die geänderten Eigenschaften. Wollen Sie nicht Ihre Benutzer müssen Sie die Anwendung erneut anpassen und wieder jedes Mal, wenn sie die Anwendung ausführen, tun Sie? Der nächste Schritt ist eine Komponente zu erstellen, die hat die Möglichkeit zum Speichern und Wiederherstellen der Klassen und Eigenschaften, die der Hersteller angibt.
TComponentStatesBeim Entwerfen der Komponente, die Komponente Eigenschaftenwerte zu speichern wollte ich machen es flexibel genug, um nur die Werte zu speichern, die der Entwickler wollte. Die Werte, die an einem Ort gespeichert werden, die leicht zugänglich und transportable wäre erforderlich. Ich wollte auch die Werte von mehr als einem Benutzer oder einer Workstation zugegriffen werden können. Aus diesen Gründen habe ich mich für die Eigenschaftenwerte in einer INI-Datei anstelle der Windows-Registrierung gespeichert.
TComponentStates arbeitet in viel tut genauso TChangeMenu durch den Zugriff auf die Routinen in PropFunc.pas speichern und Wiederherstellen von Eigenschaften der Komponente zur Laufzeit. Es gibt drei verfügbar gemachte Methoden in dieser Komponente: sichern, wiederherstellen und SetProperties. Ich denke, dass die ersten beiden sind selbsterklärend. SetProperties-Methode dient zum Festlegen einer bestimmten Eigenschaft aller Objekte im Formular, das von der gleichen Klassentyp sind. Wenn ich die Schriftart aller TDBEdit Objekte auf 'Form1' in Arial 12 ändern wollte, würde der Code so aussehen:
ComponentStates1.SetProperties (Form1, 'TDBEdit',
'Font.Name','Arial');
ComponentStates1.SetProperties (Form1, 'TDBEdit',
);
Die Routine, um dies zu erreichen ist eigentlich nicht zu kompliziert. Es verwendet die SetProperty-Methode in PropFunc.pas, wie früh besprochen. Sie durchlaufen alle Komponenten des Formulars überprüft das Classname Wenn das Classname eine Übereinstimmung ist, führt er die Methode SetProperty(), ändern Komponenteneigenschaft (siehe Codebeispiel 12).
Übersicht der 12. Die SetProperties-Methode.
Prozedur TComponentStates.SetProperties)
Const Frm:TForm
; Const sClassName:String
; Const sPropertyName:String
; Const vValue:Variant);
//****************************************************
Alle Komponenten-Eigenschaften für das Formular Frm festgelegt wo
Component.ClassName = sClassName mit vValue.
//****************************************************
Var ich: Integer;
BEGIN
Fange mit Frm
For i: = 0, (ComponentCount-1) fangen
Wenn Komponenten [i]. ClassNameIs(sClassName) dann
BEGIN
SetProperty (Komponenten [i], sPropertyName,
vValue);
Ende;
Ende;
Ende; mit Frm
Ende;
Die wichtigste Eigenschaft in dieser Komponente ist ClassesToSave. Es ist ein TStrings-Typ, der eine Liste der Klassen und Eigenschaften zum Speichern in der INI-Datei enthält. Um alle wesentlichen Informationen über jeden TPSIDBEdit zu speichern, die auf dem Formular ist, würde der Inhalt des ClassesToSave beispielsweise wie folgt aussehen:
TPSIDBEdit.Left
TPSIDBEdit.Top
TPSIDBEdit.Height
TPSIDBEdit.Width
TPSIDBEdit.TabOrder
TPSIDBEdit.Font.Name
TPSIDBEdit.Font.Size
TPSIDBEdit.Font.Style
TPSIDBEdit.Font.Color
TPSIDBEdit.Color
TPSIDBEdit.Ctl3D
TPSIDBEdit.BorderStyle
TPSIDBEdit.CharCase
Wenn die Save-Methode ausgeführt wird, würde die INI-Datei wie folgt aussehen:
[Form1]
PSIDBEdit1.Left = 313
PSIDBEdit1.Top = 319
PSIDBEdit1.Height = 21
PSIDBEdit1.Width = 121
PSIDBEdit1.TabOrder = 5
PSIDBEdit1.Font.Name = MS Sans Serif
PSIDBEdit1.Font.Size = 8
PSIDBEdit1.Font.Style = 0
PSIDBEdit1.Font.Color=-2147483640
PSIDBEdit1.Color=-2147483643
PSIDBEdit1.Ctl3D = 1
PSIDBEdit1.BorderStyle = 1
PSIDBEdit1.CharCase = 0
Speichern und Wiederherstellen-Methoden verwenden die gleiche Prozedur Prozess (siehe Listing 13) bezeichnet. Die booleschen Parameter bSpeichern befindet sich der Schalter für das Speichern und die Wiederherstellung der Werte.
Übersicht der 13. Die Process-Methode.
Prozedur TComponentStates.Process(bSave:Boolean);
Var
i, Ii: Integer;
sPropertyName: String;
sSection: String;
sClassName: String;
sID: String;
vValue: Variant;
SlPropList: TStrings;
BEGIN
Wenn nicht aktiv dann Ausfahrt;
SlPropList: = TStringList.Create;
fIniFile: = TIniFile.Create (FIniPath +
SaveToINIFileName);
Versuchen Sie
Verwenden des
Geben Sie Ihrem Kunden die Kontrolle über die gui
Geben Sie Ihrem Kunden die Kontrolle über die gui : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
Dieser Artikel beschreibt, wie Benutzer ihre GUI zur Laufzeit ändern können.
| Delphi-Entwickler | Februar 1999 |
Copyright Pinnacle Publishing, Inc. Alle Rechte vorbehalten.
Geben Sie Ihren Kunden-Kontrolle über die GUISteve Zimmelman
Wie oft haben Sie geliefert, was Sie dachte, war eine fertige Anwendung, nur zu hören Ihre Kunden sagen, 'Gee, dieses ist nett, aber ich möchte wirklich den Namen auf der linken Seite, und das Feld Status sollte rot, nicht schwarz, und...' Wäre es nicht schön, wenn alles, was Ihre Nutzer zu tun hatte war der rechten Maustaste auf das Steuerelement, und kommt ein Popup-Menü, so dass sie die Attribute des Steuerelements ändern? Oder drücken sie STRG-ArrowKey oder Shift-ArrowKey um die Position oder Größe des Steuerelements ändern?Denn Benutzer Kontrolle über die GUI ist ein zweistufiger Prozess. Zuerst müssen Sie Steuerelemente mit Eigenschaften zu erstellen, die Benutzer zur Laufzeit ändern können, und dann muss man eine Möglichkeit zum Speichern und Wiederherstellen von Änderungen. Normalerweise ist das Steuerelement, das den meisten Einsatz Ruft die DBEdit. So werden in diesem Beispiel auf konzentrieren verwendet zum Erstellen einer DBEdit, eine angepasste PopupMenu, die aktiviert wird auf der rechten Maustaste auf die Maus. Das Menü ermöglicht es den Benutzer, Text Fall Farbe, Schriftart und Tab-Reihenfolge ändern. Darüber hinaus ändert die Tastenkombination STRG-Taste und Shift-Taste die Position und Größe des Steuerelements, bzw..
Bevor ich beginne, möchte ich Sie auf eine neue Eigenschaft Text-Fall vorstellen: ProperCase. Die meisten richtigen-Koffer Konvertierungen nutzen in der Regel nur den ersten Buchstaben, dann einen beliebigen Buchstaben, die ein Leerzeichen folgt. Aber dadurch, dass eine Vielzahl von Namen und abgekürzten Titel suchen ein wenig umständlich, wie McDonald, O'Hara, M.D., und so weiter. Also in meinem Versuch, eine bessere Mausefalle zu erstellen, ich eine richtige-Koffer Konvertierung, die die Intelligenz enthalten, diese besonderen Namen zu behandeln hat. Ich stellte die Funktionen, die für die ordnungsgemäße-Koffer Umwandlung in eine Einheit namens StrFunc.pas verwendet und dann das Gerät StrFunc in den Bedeutungen der Komponente einbezogen.
Erstellen der veränderlichen DBEditDas erste, was, das ich tat, war eine neue Komponente mit TDBEdit als die übergeordnete Klasse zu erstellen. Ich rief die neue Klasse TPSIDBEdit, weil der Name des Unternehmens arbeite ich für PSI ist, und es war eine einfache Möglichkeit, um die Komponente zu unterscheiden. Als nächstes habe ich eine neuartige CharCase, die ProperCase enthält. Es wird verwendet, die DBEdit TCharCase zu überschreiben. Ich habe auch die CharCase-Eigenschaft auf eine neue Art, TPSICharCase. Neben die CharCase-Eigenschaft überschreiben, führte ich zwei neue Eigenschaften: AllowUserChange und PopupChangeMenu. Die AllowUserChange-Eigenschaft ist eine einfache boolesche Schalter, der engagiert oder trennt die Fähigkeit der Benutzer die Eigenschaften der Komponente zur Laufzeit ändern, und PopupChangeMenu ist ein Zeiger auf das PopupMenu, die wirksam ist, wenn AllowUserChange auf True festgelegt ist. Ein Großteil der Komponente ändern geschieht eigentlich durch die PopupChangeMenu, aber wird erläutert, die ein wenig später. Codebeispiel 1 präsentiert die PSIDBEdit Einheit.
Codebeispiel 1. Die PSIDBEdit-Einheit.
Einheit PSIDBEdit;
Schnittstelle
verwendet
Windows, SysUtils, Klassen, Steuerelemente, Formulare, Dialoge,
DBCtrls, Menüs, Db, StrFunc;
Typ
TPSICharCase = (EcNormal, EcUpperCase,
EcLowerCase, EcProperCase);
TPSIDBEdit = class(TDBEdit)
Private
fCharCase: TPSICharCase;
fIsChanging: Boolean;
fAllowUserChange: Boolean;
fStartMove: Boolean;
fTop: Integer;
fLeft: Integer;
fChangeMenu: TpopupMenu;
fPopupSave: TPopupMenu;
Prozedur SetAllowUserChange(Value:Boolean);
Prozedur SetChangeMenu(Value:TpopupMenu);
Prozedur SetPopUpMenu;
Prozedur SetCharCase(Value:TPSICharCase);
Procedure SetTextCase (Const bCheckState:Boolean);
geschützt
öffentliche
Verfahren geladen; Außer Kraft setzen;
Änderung der Verfahren; Außer Kraft setzen;
Verfahren KeyDown (Var Key: Word;
Verschiebung: TShiftState); außer Kraft setzen;
Verfahren MouseDown (Schaltfläche: TMouseButton; Verschiebung:
TShiftState; X, Y: Integer);
Außer Kraft setzen;
MouseMove-Prozedur (Shift: TShiftState;
X, Y: Integer); Außer Kraft setzen;
MouseUp-Prozedur (Schaltfläche: TMouseButton; Verschiebung:
TShiftState; X, Y: Integer);
Außer Kraft setzen;
veröffentlicht
Eigenschaft AllowUserChange: Boolescher
FAllowUserChange lesen
Schreiben Sie SetAllowUserChange;
CharCase Eigenschaft: TPSICharCase
FCharCase lesen
Schreiben Sie SetCharCase;
Eigenschaft PopupChangeMenu: TPopupMenu
FChangeMenu lesen
Schreiben Sie SetChangeMenu;
Ende;
Ich wollte die Komponente, die zwei Zustände haben: eine Standard-Staat, der wie sein Vorgänger Verhalten würde, und ein Design-Zustand, die es erlauben den Benutzer, seine Eigenschaften zur Laufzeit ändern. Die boolesche Eigenschaft AllowUserChange unterscheidet zwischen diesen beiden Zuständen. Wenn AllowUserChange True ist, wird die Komponente PopupMenu geändert, um auf den Wert in der PopupChangeMenu-Eigenschaft gespeicherten verweisen. Wenn es falsch ist, wird die PopupMenu-Eigenschaft auf seine früheren Entwurf Zeit Zuordnung zurückgesetzt. Darüber hinaus können die Komponente verschoben oder verkleinert werden. Ich dachte, es wäre schön für den Benutzer in der Lage, einen Unterschied zwischen den beiden Staaten, so dass ich den Cursor in CrHandPoint (-21) in der SetAllowUserChange-Methode geändert werden.
Die PopupMenu-Zuordnung wird über die SetPopupMenu-Methode geändert, wenn die AllowUserChange-Eigenschaft geändert wird.
Um die PopupMenu-Zeiger zu tauschen, wird der Standardwert PopupMenu in fPopupSave in der geladenen-Methode (siehe Listing 2) gespeichert. Anschließend wird die SetPopupMenu-Methode aufgerufen, um sicherzustellen, dass das ordnungsgemäße Popup-Menü zugewiesen wird, basierend auf dem Wert des AllowUserChange.
Codebeispiel 2. Die geladenen Methode.
Prozedur TPSIDBEdit.Loaded;
BEGIN
Versuchen Sie
Wenn (CsDesigning in ComponentState) dann Ausfahrt;
PopupMenu Zuordnung zu erfassen
fPopupSave: = PopupMenu;
SetPopupMenu;
Schließlich
Loaded geerbt;
Ende;
Ende;
Mit dem Aufkommen der neuen Text Fall ProperCase und den neuen Typ TPSICharCase musste ich komplett überschreiben und implementieren Sie erneut alle anderen standardmäßigen Text-Fall Konvertierungen in der Change-Methode der Komponente (siehe Listing 3).
Codebeispiel 3. Der Change-Methode.
Prozedur TPSIDBEdit.Change;
Var
iSelStart: Integer;
BEGIN
Versuchen Sie
Wenn (CsDesigning in ComponentState)
Oder fIsChanging dann Ausfahrt;
Cursorposition zu erfassen
iSelStart: = SelStart;
SetTextCase(False);
Cursor-Position wiederherstellen
SelStart: = iSelStart;
Schließlich
Erbte;
Ende;
Ende;
Die tatsächliche Veränderung des Textes war ein wenig schwierig. Wenn Sie den Text programmgesteuert ändern, wenn das Objekt den Fokus besitzt, und das DataSet nicht bearbeiten oder-Modus, dann die Ausnahme einfügen 'Dataset nicht im Modus bearbeiten oder einfügen' werden generiert. Also bevor Sie den Text ändern, muss die Komponente DataSet.State verhört und gegebenenfalls geändert werden. Wir müssen auch potenzielle Multiuser Konflikte behandeln, die auftreten können. Der Parameter bCheckState wird verwendet, um festzustellen, ob die DataSet.State im Modus bearbeiten oder Einfügen platziert werden, bevor Sie den Text ändern muss. Wenn dies der Fall, muss die Methode auch die Änderungen veröffentlichen. Die Post-Methode wird aufgerufen, nur wenn der Arbeitsspeicher Variable bPost auf True festgelegt ist. Listing 4 zeigt, wo all das geschieht in der SetTextCase-Methode.
Codebeispiel 4. Die SetTextCase-Methode.
Verfahren TPSIDBEdit.SetTextCase(Const bCheckState:
Boolean);
Var
bPost: Boolean;
Funktion CanChange: Boolean;
BEGIN
Versuchen Sie
Wenn nicht dann anfangen bCheckState
Ergebnis: = True;
Ausfahrt;
Ende;
Wenn (DataSource <> Nil) dann beginnen
Wenn nicht (DataSource.DataSet.State
In [DsEdit, DsInsert]) dann beginnen
Wenn DataSource.DataSet.Active dann beginnen
DataSource.DataSet.Edit;
bPost: = True;
Ende;
Ende;
Ende;
Ergebnis: = True;
Außer
Ergebnis: = False;
Ende;
Ende;
BEGIN
Wenn die Textänderungen und dem DataSet
ist nicht in EditState, dann eine Ausnahme
wird generiert. Stellen Sie sicher, dass DataSet ist
in EditState vor dem Ändern von Text.
fIsChanging: = True;
Versuchen Sie
bPost: = False;
Wenn CanChange dann beginnen
RS CharCase der
EcNormal: {Do Nothing};
EcUpperCase: Text: = UpperCase(Text);
EcLowerCase: Text: = LowerCase(Text);
EcProperCase: Text: = ToProper(Text);
Ende;
Wenn dann bPost
DataSource.DataSet.Post;
Anderes Ende
MessageDlg (' ein anderer Benutzer verwenden möglicherweise dies ' +
'Datensatz.' + #13 #13 +
' TextCase Änderungen möglicherweise nicht ' +
'sichtbaren für diesen Eintrag.',
mtWarning,[mbOK],0);
Schließlich
fIsChanging: = False;
Ende;
Ende;
Ändern der CharCase-Eigenschaft führt die SetCharCase-Methode (siehe Listing 5), die wiederum die SetTextCase-Methode ausgeführt wird.
Übersicht der 5. Die SetCharCase-Methode.
Prozedur TPSIDBEdit.SetCharCase(Value:TPSICharCase);
BEGIN
Dann beginnen Sie, wenn fCharCase <> Wert
fCharCase: = Value;
SetTextCase(True);
Ende;
Ende;
Damit das Steuerelement Bewegungsmöglichkeiten haben overrode ich das KeyDown-Verfahren (siehe Listing 6). Kreditaufnahme die Delphi IDE Tastatureingaben für Komponente verschieben und Ändern der Größe, habe ich die STRG-ArrowKeys für Bewegung und Shift-ArrowKeys für die Größenanpassung. Diese Tasten drücken, wird das Steuerelement seine Größe oder Position um ein Pixel zu ändern.
Inserat 6. Das KeyDown-Methode.
Procedure TPSIDBEdit.KeyDown (Var Key: Word;
Verschiebung: TShiftState);
BEGIN
Wenn (geben Sie [Vk_up, Vk_down, Vk_left Vk_right])
Und AllowUserChange Then Begin
Wenn (Shift = [SsCtrl]) dann beginnen
Position ändern
Case-Schlüssel von
Vk_Up: Top: = Top - 1;
Vk_Down: Top: = Top + 1;
Vk_Left: Links: = Left - 1;
Vk_Right: Links: = Links + 1;
Ende;
End Else If (Shift = [SsShift]) dann beginnen
Größe ändern
Case-Schlüssel von
Vk_Up: Höhe: = Höhe - 1;
Vk_Down: Höhe: = Höhe + 1;
Vk_Left: Breite: = Breite - 1;
Vk_Right: Breite: = Breite + 1;
Ende;
Ende;
Schlüssel: = 0;
End Else Begin
geerbte KeyDown(Key,Shift);
Ende;
Ende;
Ich wollte auch den Benutzer die Komponente mit der Maus verschieben, so dass ich die Methoden MouseDown, MouseUp und MouseMove overrode.
So weit, ist was du hast eine DBEdit, die einem Benutzer ermöglicht, seine Position und Größe, aber kaum etwas anderes ändern. Schriftart, Farbe, Tab-Reihenfolge, 3D-Effekt und Grenze erfolgt mit dem Zusatz der Komponente ChangeMenu.
Die Grundlage für diese Komponente ist in der Einheit TypInfo.pas, gefunden, die Sie auf ein Objekt RTTI (Laufzeit-Typinformationen) zugreifen können. TypInfo.pas enthält Funktionen und Prozeduren, die abrufen oder eine Objekt-Eigenschaftenwerte während der Ausführung der Anwendung festlegen können. Einige einfachen Methoden festlegen oder Abrufen Eigenschaftenwert eines Objekts zur Laufzeit können wie Listing 7 aussehen.
Übersicht der 7. Abrufen und Festlegen von-Eigenschaft eines Objekts zur Laufzeit.
Funktion GetProperty(Sender:TComponent
sPropName:String): Variante
Var
PropInfo: PPropinfo;
BEGIN
Erhalten Sie aus den Klasseninformationen die Eigenschaft
PropInfo: = GetPropInfo (Sender.ClassInfo,
sPropName);
Existiert die Eigenschaft?
Wenn (PropInfo <> Nil) dann beginnen
Rs. Propinfo ^. PropType ^. Eine Art
TkEnumeration, TkInteger:
BEGIN
Ergebnis: = GetOrdProp(Sender,PropInfo)
Ende;
TkString, TkLString, TkWString:
BEGIN
Ergebnis: = GetStrProp(Sender,PropInfo)
Ende;
Ende;
Anderes Ende
Ergebnis: = Null;
Ende;
Verfahren SetProperty(Sender:TComponent
; sPropName:String
vValue:Variant)
Var
PropInfo: PPropinfo;
BEGIN
Erhalten Sie aus den Klasseninformationen die Eigenschaft
PropInfo: = GetPropInfo (Sender.ClassInfo,
sPropName);
Existiert die Eigenschaft?
Wenn (PropInfo <> Nil) dann beginnen
Rs. Propinfo ^. PropType ^. Eine Art
TkEnumeration, TkInteger:
BEGIN
SetOrdProp(Sender,PropInfo,vValue);
Ende;
TkString, TkLString, TkWString:
BEGIN
SetStrProp(Sender,PropInfo,vValue);
Ende;
Ende;
Ende;
Ende;
Verwendung dieser beiden Methoden könnte wie folgt aussehen:
SetProperty(DBEdit1,'Ctl3D',False);
DBEdit2.Ctrl3D: = GetProperty(DBEdit1.'Ctl3D');
Zugegeben, können dieses Beispiel ist wahrscheinlich vereinfachenden, Verfahren wie diese jedoch ganz praktisch, wenn Sie nicht, den Komponentennamen, oder sogar seiner Klasse wissen.
Die drei wichtigsten Methoden in ChangeMenu--GetProperty(), SetProperty() und IsProperty()--verwendet werden in der Einheit PropFunc.pas gefunden, die Teil dieser Bibliothek ist. IsProperty() ist eine boolesche Funktion, die prüft, ob eine angegebene Eigenschaft in einem Objekt und gibt den Wert true, wenn die Eigenschaft vorhanden ist. Es kann sein etwas wie folgt verwendet:
Wenn dann die IsProperty(Form1.Components[i],'Ctl3D')
Komponenten [i]. Ctl3d: = False;
TChangeMenu ist eine Unterklasse des TPopupMenu mit zwei zusätzliche Eigenschaften: FontDialog und ColorDialog, die werden verwendet, um der Komponente Schriftart und Farbe ändern und können auf jede passende Klassentypen, die im Bereich der Komponente zeigen. Die Methoden MenuClick und OnMenuPopup den Großteil der Arbeit zu tun und sind die Ereignisse OnClick und OnPopup der Menüelemente zugewiesen, wenn die Komponente erstellt wird. All dies geschieht natürlich in der ChangeMenu-Einheit (siehe Codebeispiel 8).
Übersicht der 8. Die ChangeMenu-Einheit.
Einheit ChangeMenu;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Klassen, Grafiken,
Steuerelemente, Formulare, Dialogfelder, Menüs, Comctrls,
StdCtrls, Dbctrls, Db, Extctrls;
Typ
TChangeMenu = class(TPopupMenu)
Private
{Private Deklarationen}
Pm_Font: TMenuItem;
Pm_bgColor: TMenuItem;
Pm_TabOrder: TMenuItem;
pm_Ctrl3D: TMenuItem;
Pm_BorderStyle: TMenuItem;
Pm_Columns: TMenuItem;
Pm_Caption: TMenuItem;
pm_Divider1: TMenuItem;
Pm_UpperCase: TMenuItem;
Pm_LowerCase: TMenuItem;
Pm_MixedCase: TMenuItem;
Pm_ProperCase: TMenuItem;
Pm_Height: TMenuItem;
Pm_Width: TMenuItem;
Pm_Style: TMenuItem;
fFontDialog: TFontDialog;
fColorDialog: TColorDialog;
Prozedur SetColorDialog(Value:TColorDialog);
Prozedur SetFontDialog(Value:TFontDialog);
Prozedur MenuClick(Sender:TObject);
Prozedur OnMenuPopup(Sender:TObject);
geschützt
{Protected Deklarationen}
öffentliche
{Public Deklarationen}
Verfahren geladen; Außer Kraft setzen;
Destruktor zerstören; außer Kraft setzen;
Konstruktor Create(AOwner: TComponent); außer Kraft setzen;
veröffentlicht
{Veröffentlichten Erklärungen}
FontDialog Eigenschaft: TFontDialog
FFontDialog lesen
Schreiben Sie SetFontDialog;
ColorDialog Eigenschaft: TColorDialog
FColorDialog lesen
Schreiben Sie SetColorDialog;
Ende;
Register des Verfahrens;
Umsetzung
verwendet PropFunc, Col_edit;
Aufgrund der speziellen Einsatzbereich dieses Menüs werden die Menüelemente nur während der Laufzeit nicht zur Entwurfszeit in der IDE erstellt. Nachdem die Menüpunkte erstellt wurden, wird die Methode OnClick-Ereignis jedes Menüelement MenuClick() zugewiesen. Das Menü wird wie in Abbildung 1 aussehen.
Die geladene-Methode (siehe Listing 9) erfasst den Zeiger auf die Komponente OnPopup Methode, dann weist das OnPopup-Ereignis an die Methode OnMenuPoup(). Dies geschieht, damit der Entwickler OnPopup Methode ausgeführt wird, nachdem die OnMenuPopup-Methode eine eigene Menüelemente Verarbeitung beendet hat.
Codebeispiel 9. Die geladenen Methode.
Prozedur TChangeMenu.Loaded;
BEGIN
Versuchen Sie
Zeiger in der Komponente OnPopup Methode speichern
FOtherOnPopup: = OnPopup;
OnPopup-Methode zuweisen
OnPopup: = OnMenuPopup;
Schließlich
Erbte;
Ende;
Ende;
Wenn der Benutzer die Maus über die Komponente klickt, die OnMenuPopup Methode ist ausgeführt (siehe Listing 10) und initialisiert die Menüelemente basierend auf das Menü PopupComponent-Eigenschaft. PopupComponent ist ein Zeiger auf das Objekt, das Aktivieren des Menüs verantwortete und Typ TComponent. Beachten Sie die Verwendung der Methode IsProperty die sichtbare-Eigenschaft der Menüelemente festgelegt.
Liste der 10. Die OnMenuPopup-Methode.
Prozedur TChangeMenu.OnMenuPopup(Sender:TObject);
Initialisieren Sie Menüelemente auf der Grundlage der
konzentrierte sich Art und Eigenschaften der Komponente.
Var bSet: Boolean;
BEGIN
Keine Schriftart anzeigen Posten, wenn die Schriftart
Dialogfeld Eigenschaft ist Nil oder die Schriftart
Eigenschaft existiert nicht in der fokussierten
Komponente.
pm_Font.Visible: =
(Nicht (FontDialog = Nil))
Und IsProperty(PopupComponent,'Font');
Farbe zeigen nicht Posten, wenn die ColorDialog
Eigenschaft ist Nil oder die Color-Eigenschaft nicht
gibt es in der fokussierten Komponente.
pm_bgColor.Visible: =
Nicht (ColorDialog = Nil)
Und IsProperty(PopupComponent,'Color');
Initialisieren-Radio und aktivierten Menüpunkte
Wenn IsProperty (PopupComponent,
'BorderStyle') dann Begin
pm_BorderStyle.Checked: =
(GetProperty (PopupComponent,
'BorderStyle') = BsSingle);
pm_BorderStyle.Visible: = True;
End Else Begin
pm_BorderStyle.Visible: = False;
Ende;
Wenn IsProperty(PopupComponent,'Ctl3D') dann beginnen
pm_Ctrl3D.Checked: =
GetProperty(PopupComponent,'Ctl3D');
pm_Ctrl3D.Visible: = True;
End Else Begin
pm_Ctrl3D.Visible: = False;
Ende;
Wenn die Eigenschaft TabOrder in der Komponente vorhanden ist,
zeigen Sie das Menüelement 'Tab-Reihenfolge'.
pm_TabOrder.Visible:=
IsProperty(PopupComponent,'TabOrder');
Wenn die Columns-Eigenschaft in der Komponente vorhanden ist
und die Komponente ist TListView,
zeigen Sie das Menüelement.
If (PopupComponent TListView) dann
Pm_columns. Sichtbar: =
(IsProperty(PopupComponent,'Columns') und
(TListView(PopupComponent). Columns.Count > 0))
Sonst
Pm_columns. Sichtbar: = False;
Sie sollten nun die Idee haben...
pm_Caption.Visible: =
IsProperty(PopupComponent,'Caption');
Wenn die fokussierte Komponente verfügt über CharCase und
Eigenschaften der AllowUser ändern, dann verarbeiten mehr
Menüelemente.
Wenn (IsProperty(PopupComponent,'CharCase')
Und IsProperty (PopupComponent,
'AllowUserChange')) dann Begin
bSet: = True;
CharCase Elemente zeigen nicht wenn die
DataType nicht String.
Wenn IsProperty (PopupComponent,
'DataSource') dann Begin
If (PopupComponent TDBEdit) dann beginnen
Mit TDBEdit(PopupComponent) fangen
Wenn (DataField <> cm) dann beginnen
Wenn nicht (Field.DataType =
FtString) dann beginnen
bSet: = False;
Ende;
Anderes Ende
bSet: = False;
Ende;
Ende;
Ende;
pm_UpperCase.Visible: = bSet;
pm_LowerCase.Visible: = bSet;
pm_MixedCase.Visible: = bSet;
pm_ProperCase.Visible: = bSet;
pm_Divider1.Visible: = bSet;
CharCase Radio-Objekte zu initialisieren.
RS GetProperty(PopupComponent,'CharCase') der
ecNormal
0: pm_MixedCase.Checked: = True;
ecUpperCase
1: pm_UpperCase.Checked: = True;
ecLowerCase
2: pm_LowerCase.Checked: = True;
ecProperCase
3: pm_ProperCase.Checked: = True;
Ende;
End Else Begin
pm_UpperCase.Visible: = False;
pm_LowerCase.Visible: = False;
pm_MixedCase.Visible: = False;
pm_ProperCase.Visible: = False;
pm_Divider1.Visible: = False;
Ende;
pm_Width.Visible: = (PopupComponent ist TBevel);
pm_Height.Visible: = (PopupComponent ist TBevel);
pm_Style.Visible: = (PopupComponent ist TBevel);
Wenn pm_Style.Visible dann beginnen
Wenn GetProperty (PopupComponent, 'Stil') = 0 Then
pm_Style.Caption: = 'Bevel ausgelöst'
Sonst
pm_Style.Caption: = 'Senkte Abschrägung';
Ende;
Führen Sie OnPopup-Ereignis der Komponente.
Wenn Assigned(FOtherOnPopup) dann
FOtherOnPopup(Sender);
Ende;
Wenn ein Element wird aktiviert (siehe Codebeispiel 11) dient die Methode SetProperty() Eigenschaftenwerte des Objekts zu ändern.
Codebeispiel 11. Die MenuClick-Methode.
Prozedur TChangeMenu.MenuClick(Sender:TObject);
Prozess der Menü-Auswahl für die gezielte
Komponente.
Var
String: String;
i, iInt: Integer;
b: Boolean;
BEGIN
Wenn (TMenuItem(Sender) = pm_Ctrl3D) dann beginnen
Prozess-3D - 3D ausgewählt ist
dann muss die BorderStyle-Eigenschaft geändert werden
in Single.
b: = nicht Boolean (GetProperty (PopupComponent,
'Ctl3D'));
SetProperty(PopupComponent,'Ctl3D',Ord(b));
Wenn b und (GetProperty (PopupComponent,
'BorderStyle') = BsNone) dann
SetProperty (PopupComponent,
'BorderStyle', BsSingle);
Sonst endif (TMenuItem(Sender) =
Pm_BorderStyle) dann beginnen
Prozess-BorderStyle
Wenn (GetProperty (PopupComponent,
'BorderStyle') = BsSingle) dann beginnen
SetProperty (PopupComponent,
'BorderStyle', BsNone);
Wenn die BorderStyle-Eigenschaft auf None festgelegt ist
3D ausschalten.
SetProperty(PopupComponent,'Ctl3D',False);
Anderes Ende
SetProperty (PopupComponent,
'BorderStyle', BsSingle);
Sonst endif (TMenuItem(Sender) =
Pm_TabOrder) dann beginnen
Prozess-TabOrder
String: = IntToStr (GetProperty (PopupComponent,
'TabOrder'));
Versuchen Sie
String: = InputBox ('Set Aktivierreihenfolge',
'Geben Sie die Tab-Reihenfolge', String);
iInt: = StrToInt(sString);
SetProperty(PopupComponent,'TabOrder',iInt);
Außer
Exception.Create zu erhöhen ('Registerkarte Reihenfolge muss ' +
'Integer sein');
Ende;
End Else If (TMenuItem(Sender) = Pm_Font) dann beginnen
Auswahl von Schriftarten
Wenn (FontDialog-<>-Nil) dann beginnen
FontDialog.Font.Name: =
GetProperty(PopupComponent,'Font.Name');
FontDialog.Font.Size: =
GetProperty(PopupComponent,'Font.Size');
FontDialog.Font.Color: =
GetProperty(PopupComponent,'Font.Color');
FontDialog.Font.Style: =
TFontStyles (TFontStyle)
GetProperty(PopupComponent,'Font.Style')));
Wenn FontDialog.Execute dann beginnen
SetProperty (PopupComponent,'Font.Name '
FontDialog.Font.Name);
SetProperty (PopupComponent,'Font.Size ',
FontDialog.Font.Size);
SetProperty (PopupComponent,'Font.Color ',
FontDialog.Font.Color);
SetProperty (PopupComponent,'Font.Style ',
Ord(TFontStyle(FontDialog.Font.Style)));
Erzwingen Sie Schrifthöhe aktualisieren
die Komponente
i: = GetProperty(PopupComponent,
'Font.Height');
SetProperty (PopupComponent,
' Font.Height',i+(-5));
SetProperty (PopupComponent,
);
Ende;
Ende;
Sonst endif (TMenuItem(Sender) =
Pm_BgColor) dann beginnen
Prozessfarbe
Wenn dann ColorDialog <> Nil beginnen
ColorDialog.Color: =
GetProperty(PopupComponent,'Color');
Wenn ColorDialog.Execute dann beginnen
SetProperty (PopupComponent, 'Farbe',
ColorDialog.Color);
Ende;
Ende;
Sonst endif (TMenuItem(Sender) =
Pm_Caption) dann beginnen
Prozess-Beschriftung
String: = GetProperty(PopupComponent,'Caption');
String: = InputBox ('Beschriftung ändern',
'Geben Sie die Beschriftung', String);
SetProperty(PopupComponent,'Caption',sString);
Sonst endif (TMenuItem(Sender) =
& n SP; Pm_columns) dann beginnen
Prozess-Spalten für TListView. Dies geschieht
mit einer äußeren Form.
Application.CreateForm (TfrmEditColumns,
FrmEditColumns);
Versuchen Sie
frmEditColumns.ColObject: =
TListView(PopupComponent);
frmEditColumns.ShowModal;
Schließlich
frmEditColumns.Free;
Ende;
Anderes Ende wenn (TMenuItem(Sender)=pm_Width) dann beginnen
Prozess-Breite für TBevel
String: = IntToStr (GetProperty (PopupComponent,
'Breite'));
Versuchen Sie
String: = InputBox ('Breite festlegen',
'Geben Sie Breite', String);
iInt: = StrToInt(sString);
SetProperty(PopupComponent,'Width',iInt);
Außer
Exception.Create zu erhöhen ('Breite muß ' +
'Ein Integer');
Ende;
Anderes Ende wenn (TMenuItem(Sender)=pm_Height) dann beginnen
Prozess-Höhe für TBevel
String: = IntToStr (GetProperty (PopupComponent,
'Höhe'));
Versuchen Sie
String: = InputBox ('Höhe festlegen',
'Geben Sie die Höhe', String);
iInt: = StrToInt(sString);
SetProperty(PopupComponent,'Height',iInt);
Außer
Exception.Create erhöhen (' Höhe muß ' +
'Ein Integer');
Ende;
Anderes Ende wenn (TMenuItem(Sender)=pm_Style) dann beginnen
Prozess-Bevel-Stype für TBevel
Angehoben oder gesenkt
Wenn GetProperty (PopupComponent, 'Stil') = 0 Then
SetProperty(PopupComponent,'Style',1)
Sonst
SetProperty(PopupComponent,'Style',0)
End Else Begin
TMenuItem(Sender). Geprüft: =
Nicht TMenuItem(Sender). Geprüft;
Wenn pm_MixedCase.Checked dann beginnen
Normal
SetProperty(PopupComponent,'CharCase',0);
End Else If pm_UpperCase.Checked dann beginnen
CharCase: = EcUpperCase;
SetProperty(PopupComponent,'CharCase',1);
End Else If pm_LowerCase.Checked dann beginnen
CharCase: = EcLowerCase;
SetProperty(PopupComponent,'CharCase',2);
End Else If pm_ProperCase.Checked dann beginnen
CharCase: = EcProperCase;
SetProperty(PopupComponent,'CharCase',3);
Ende;
Ende;
Ende;
TChangeMenu kann eigentlich auf fast allen standard-Bauteil verwendet werden, die die unterstützten Eigenschaften hat. Es unterstützt sogar TListView Spaltenüberschriften und breiten.
Halb esErstellen einer Komponente, die dem Benutzer erlaubt, seine Größe, Position, Schriftart, Farbe und So weiter zu ändern, ist gut. Aber es ist nicht sehr hilfreich, ohne die Fähigkeit also speichern und Wiederherstellen die geänderten Eigenschaften. Wollen Sie nicht Ihre Benutzer müssen Sie die Anwendung erneut anpassen und wieder jedes Mal, wenn sie die Anwendung ausführen, tun Sie? Der nächste Schritt ist eine Komponente zu erstellen, die hat die Möglichkeit zum Speichern und Wiederherstellen der Klassen und Eigenschaften, die der Hersteller angibt.
TComponentStatesBeim Entwerfen der Komponente, die Komponente Eigenschaftenwerte zu speichern wollte ich machen es flexibel genug, um nur die Werte zu speichern, die der Entwickler wollte. Die Werte, die an einem Ort gespeichert werden, die leicht zugänglich und transportable wäre erforderlich. Ich wollte auch die Werte von mehr als einem Benutzer oder einer Workstation zugegriffen werden können. Aus diesen Gründen habe ich mich für die Eigenschaftenwerte in einer INI-Datei anstelle der Windows-Registrierung gespeichert.
TComponentStates arbeitet in viel tut genauso TChangeMenu durch den Zugriff auf die Routinen in PropFunc.pas speichern und Wiederherstellen von Eigenschaften der Komponente zur Laufzeit. Es gibt drei verfügbar gemachte Methoden in dieser Komponente: sichern, wiederherstellen und SetProperties. Ich denke, dass die ersten beiden sind selbsterklärend. SetProperties-Methode dient zum Festlegen einer bestimmten Eigenschaft aller Objekte im Formular, das von der gleichen Klassentyp sind. Wenn ich die Schriftart aller TDBEdit Objekte auf 'Form1' in Arial 12 ändern wollte, würde der Code so aussehen:
ComponentStates1.SetProperties (Form1, 'TDBEdit',
'Font.Name','Arial');
ComponentStates1.SetProperties (Form1, 'TDBEdit',
);
Die Routine, um dies zu erreichen ist eigentlich nicht zu kompliziert. Es verwendet die SetProperty-Methode in PropFunc.pas, wie früh besprochen. Sie durchlaufen alle Komponenten des Formulars überprüft das Classname Wenn das Classname eine Übereinstimmung ist, führt er die Methode SetProperty(), ändern Komponenteneigenschaft (siehe Codebeispiel 12).
Übersicht der 12. Die SetProperties-Methode.
Prozedur TComponentStates.SetProperties)
Const Frm:TForm
; Const sClassName:String
; Const sPropertyName:String
; Const vValue:Variant);
//****************************************************
Alle Komponenten-Eigenschaften für das Formular Frm festgelegt wo
Component.ClassName = sClassName mit vValue.
//****************************************************
Var ich: Integer;
BEGIN
Fange mit Frm
For i: = 0, (ComponentCount-1) fangen
Wenn Komponenten [i]. ClassNameIs(sClassName) dann
BEGIN
SetProperty (Komponenten [i], sPropertyName,
vValue);
Ende;
Ende;
Ende; mit Frm
Ende;
Die wichtigste Eigenschaft in dieser Komponente ist ClassesToSave. Es ist ein TStrings-Typ, der eine Liste der Klassen und Eigenschaften zum Speichern in der INI-Datei enthält. Um alle wesentlichen Informationen über jeden TPSIDBEdit zu speichern, die auf dem Formular ist, würde der Inhalt des ClassesToSave beispielsweise wie folgt aussehen:
TPSIDBEdit.Left
TPSIDBEdit.Top
TPSIDBEdit.Height
TPSIDBEdit.Width
TPSIDBEdit.TabOrder
TPSIDBEdit.Font.Name
TPSIDBEdit.Font.Size
TPSIDBEdit.Font.Style
TPSIDBEdit.Font.Color
TPSIDBEdit.Color
TPSIDBEdit.Ctl3D
TPSIDBEdit.BorderStyle
TPSIDBEdit.CharCase
Wenn die Save-Methode ausgeführt wird, würde die INI-Datei wie folgt aussehen:
[Form1]
PSIDBEdit1.Left = 313
PSIDBEdit1.Top = 319
PSIDBEdit1.Height = 21
PSIDBEdit1.Width = 121
PSIDBEdit1.TabOrder = 5
PSIDBEdit1.Font.Name = MS Sans Serif
PSIDBEdit1.Font.Size = 8
PSIDBEdit1.Font.Style = 0
PSIDBEdit1.Font.Color=-2147483640
PSIDBEdit1.Color=-2147483643
PSIDBEdit1.Ctl3D = 1
PSIDBEdit1.BorderStyle = 1
PSIDBEdit1.CharCase = 0
Speichern und Wiederherstellen-Methoden verwenden die gleiche Prozedur Prozess (siehe Listing 13) bezeichnet. Die booleschen Parameter bSpeichern befindet sich der Schalter für das Speichern und die Wiederherstellung der Werte.
Übersicht der 13. Die Process-Methode.
Prozedur TComponentStates.Process(bSave:Boolean);
Var
i, Ii: Integer;
sPropertyName: String;
sSection: String;
sClassName: String;
sID: String;
vValue: Variant;
SlPropList: TStrings;
BEGIN
Wenn nicht aktiv dann Ausfahrt;
SlPropList: = TStringList.Create;
fIniFile: = TIniFile.Create (FIniPath +
SaveToINIFileName);
Versuchen Sie
Verwenden des
Geben Sie Ihrem Kunden die Kontrolle über die gui
By Wiezutun
Geben Sie Ihrem Kunden die Kontrolle über die gui : Mehreren tausend Tipps, um Ihr Leben einfacher machen.