Bonjour à tous,
Je me suis bien pris la tête sur ce point alors, comme ça m'a servi, peut être servira-t-il aux autres
L'assignation des éléments d'une combobox copie les objets associés alors que l'assignation des éléments d'un mémo ne copie pas les objets.
Pourquoi ?
Bien que les éléments d'un mémo et d'une combobox soient tous deux de type TStrings, leur fonctionnement diffère.
1. Pour un memo, les éléments ont pour propriété 'Lines'
Il dérive de TCustomMemo
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 TMemo = class(TCustomMemo) published ... property Lines;
La variable private s'appelle FLines et on va voir comment elle est créée...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 TCustomMemo = class(TCustomEdit) private ... protected ... public ... property Lines: TStrings read FLines write SetLines; end;
Il n'y a pas de TMemo.Create.
On passe à TCustomMemo. Create :
FLines est donc de type TMemoStrings.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 constructor TCustomMemo.Create(AOwner: TComponent); begin ... FLines := TMemoStrings.Create; ... end;
Le Assign n'est pas présent dans TMemoStrings, on monte à TStrings.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 TMemoStrings = class(TStrings) private Memo: TCustomMemo; protected function Get(Index: Integer): string; override; function GetCount: Integer; override; function GetTextStr: string; override; procedure Put(Index: Integer; const S: string); override; procedure SetTextStr(const Value: string); override; procedure SetUpdateState(Updating: Boolean); override; public procedure Clear; override; procedure Delete(Index: Integer); override; procedure Insert(Index: Integer; const S: string); override; end;
On regarde AddStrings :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 procedure TStrings.Assign(Source: TPersistent); begin ... AddStrings(TStrings(Source)); ... end;
On regarde AddObject :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 procedure TStrings.AddStrings(Strings: TStrings); begin ... AddObject(Strings[I], Strings.Objects[I]); end;
On regarde PutObject :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 function TStrings.AddObject(const S: string; AObject: TObject): Integer; begin Result := Add(S); PutObject(Result, AObject); end;
-> Ne fait rien... Cool
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 procedure TStrings.PutObject(Index: Integer; AObject: TObject); begin end;
2. Pour un combo, les éléments ont pour propriété items
Dérive de TCustomComboBox
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 TComboBox = class(TCustomComboBox) published ... property Items; { Must be published after OnMeasureItem } end;
qui n'a pas items de défini
Code : Sélectionner tout - Visualiser dans une fenêtre à part TCustomComboBox = class(TCustomCombo)
Il dérive de TCustomCombo
La variable private est donc FItems.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 TCustomCombo = class(TCustomListControl) private ... protected ... public ... property Items: TStrings read FItems write SetItems; ... end;
On regarde si le create de TCustomCombo la définit...
-> Non...
On regarde donc si le create de TCustomComboBox la définit...
Oui... Donc FItems est de type GetItemsClass (sans doute descendant de TStrings...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 constructor TCustomComboBox.Create(AOwner: TComponent); begin ... FItems := GetItemsClass.Create; ... end;
En fait, GetItemsClass est une fonction qui renvoie la classe TCustomComboBoxStringsClass
Code : Sélectionner tout - Visualiser dans une fenêtre à part TCustomComboBoxStringsClass = class of TCustomComboBoxStrings;PutObject, défini à vide en TStrings est ici déclaré...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 TCustomComboBoxStrings = class(TStrings) private ... protected ... procedure PutObject(Index: Integer; AObject: TObject); override; ... public ... end;
...et pas vide
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 procedure TCustomComboBoxStrings.PutObject(Index: Integer; AObject: TObject); begin SendMessage(ComboBox.Handle, CB_SETITEMDATA, Index, Longint(AObject)); end;
Voilà donc pourquoi le assign sur les éléments d'un Combo et d'un Memo sont différents, bien que les éléments Lines et Items soient de même type...
Comme ils sont créés avec des types différents, l'un surcharge la copie des objets, ce que l'autre ne fait pas...
Hope it helps![]()
Partager