Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Property Read Only bei Combobox hinzufügen (Style = csSimple) (https://www.delphipraxis.net/163992-property-read-only-bei-combobox-hinzufuegen-style-%3D-cssimple.html)

RWarnecke 24. Okt 2011 19:05

Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
Hallo zusammen,

da ich eine Combobox suche, die eine Read Only Eigenschaft hat und bis jetzt keine passende gefunden habe, die für 32Bit & 64Bit funktioniert habe ich mal in meinen alten Beispielen gesucht und auch etwas gefunden.

Delphi-Quellcode:
type
  TComboBoxReadOnly = class(TComboBox)
  private
    FReadOnly: Boolean;
    procedure SetReadOnly(const Value: Boolean);
  public
    { Public-Deklarationen }
  published
    property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
  end;

implementation

procedure TComboBoxReadOnly.SetReadOnly(const Value: Boolean);
begin
  if FReadOnly <> Value then
  begin
    FReadOnly := Value;
    if HandleAllocated then
      SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
  end;
end;
Wenn der Style der Combobox auf csDropDown steht, funktioniert das Read Only zumindest für die Texteingabe hervorragend. Jetzt gibt es noch zwei kleine Problemchen. Ich hätte die Option Read Only auch beim Style csSimple. Ich habe noch nicht so viele Komponeten abgeleitet und verändert. Was müsste ich noch hinzufügen oder ändern, dass die Read Only Option auch im Style csSimple funktioniert ?
Das zweite Problem ist, dass wenn ich die Property ReadOnly auf True setze im Style csDropDown, kann ich den Wert aus der Combobox immer noch ändern. Wie kann ich da die Auswahl der Werte abstellen ?

Es können auch ein paar Links sein, wo ich mir das ganze nachlesen kann.

ConnorMcLeod 24. Okt 2011 21:10

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
Und es genügt nicht ...
Delphi-Quellcode:
Style := csDropDownList;
? Danach kann man nix mehr eintippen, nur noch aus der vorhandenen Liste auswählen.

Bummi 24. Okt 2011 21:49

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
da beim Ändern der Styles ein RecreateWnd gefahren wird solltest Du IMHO so vorgehen

die Prüfung "if FReadOnly <> Value then" entfernen ...

und SetStyle überschreiben

Delphi-Quellcode:
procedure SetStyle(Value: TComboBoxStyle);override;

procedure TComboBoxReadOnly.SetReadOnly(const Value: Boolean);
begin

  begin
    FReadOnly := Value;
    if HandleAllocated then
      SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
  end;
end;

procedure TComboBoxReadOnly.SetStyle(Value: TComboBoxStyle);
begin
  inherited;
  ReadOnly := FReadOnly;
end;

himitsu 24. Okt 2011 22:19

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
Er braucht nur auf das Neuerstellen des internen Crontrols zu reagieren.
Denn wurde beim erstellen die interne Komponente noch nicht erstellt, aber der DFM-Loader läd schon das ReadOnly-Property, da wird dieses ebenfalls nicht beachtet, wenn die Komonente dann mal erstellt wird.

Und es kann auch gut sein, das nicht nur SetStyle ein Neuerstellen verursacht ... dann müßte man ja alles Mögliche so abfangen ... oder man klinkt sich eben nur einmal in das Neuerstellen ein. :angle:

Bummi 24. Okt 2011 22:27

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
@himitsu
auch wenn ich Dir prinzipiell Recht gebe dürfte das erheblich aufwändiger sein da RecreateWnd deutlich tiefer in der Klassenhierarchie liegt und nicht virtuell implementiert ist.

himitsu 24. Okt 2011 22:45

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
stümmt, das ist nicht virtual/dynamic, aber
CreateWnd und CreateWindowHandle sind virtual und protected ... an eines davon kommt man also recht einfach ran

RecreateWnd sendet (zumindest in D2010) nur ein CM_RECREATEWND ab (welches man abfangen könnte) und auch nur, wenn das Fenster wirklich existiert.
Ein nichtexistierendes Fenster wird nicht (neu) erstellt.

RWarnecke 25. Okt 2011 06:33

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
Hallo zusammen,

danke erstmal für eure Antworten.
Zitat:

Zitat von ConnorMcLeod (Beitrag 1132331)
Und es genügt nicht ...
Delphi-Quellcode:
Style := csDropDownList;
? Danach kann man nix mehr eintippen, nur noch aus der vorhandenen Liste auswählen.

Nein, das reicht in dem Falle nicht. Ich möchte bei der Maske einen Lese-Modus und einen Schreibmodus haben.
Beim Lese-Modus soll es keine Möglichkeit geben, den Wert im Textfeld der Combobox zu ändern, daher der Style csSimple. Im Schreibenmodus sollen nur die Eingaben angenommen werden, die auch als Position in der Combobox stehen oder man soll sich eine Position aus der Liste per Maus auswählen.

@bummi & himitsu:
Wenn ich euch beide richtig verstanden habe, muss ich nur RecreateWnd und/oder CreateWnd überschreiben, nur verstehe ich da noch nicht ganz den Hintergrund. Wenn ich die Combobox in den Style csSimple setze habe ich ja lediglich ein sogenanntes Editfeld. Wenn ich darin jetzt eine Eingabe mache und bei den Items etwas drinsteht und diese beiden Sachen übereinstimmen, wird mir die Position ja vorgeschlagen. Wenn ich jetzt die Property Autocomplete auf False setze, dann schalte ich zumindest schonmal den Vorschlag ab, kann aber immer noch etwas eingeben. Deshalb vermute ich mal, dass ich für den ReadOnly Betrieb nur noch eine weitere Zeile honzufügen oder die bestehende Zeile ändern muss für den Style csSimple.

Bummi 25. Okt 2011 06:46

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
mhhhh, ob wir jetzt alles erwischt haben ....

Delphi-Quellcode:
type
  TComboBoxReadOnly = class(TComboBox)
  private
    FReadOnly: Boolean;
    procedure SetReadOnly(const Value: Boolean);
   procedure KeyPress(var Key: Char);override;
   Procedure CreateWnd;Override;
  public
    { Public-Deklarationen }
  published
    property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
  end;




procedure TComboBoxReadOnly.CreateWnd;
begin
  inherited;
  ReadOnly := FReadOnly;
end;

procedure TComboBoxReadOnly.KeyPress(var Key: Char);
begin
  if not readonly then inherited;

end;

procedure TComboBoxReadOnly.SetReadOnly(const Value: Boolean);
begin

  begin
    FReadOnly := Value;
    if HandleAllocated then
      SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
  end;
end;

himitsu 25. Okt 2011 07:33

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
Hintergrund ist Folgender:
Delphi-Quellcode:
procedure TComboBoxReadOnly.SetReadOnly(Value: Boolean);
begin
  ...
  if HandleAllocated then
    SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
end;
Du setzt EM_SETREADONLY nur, wenn die interne Komponente vorhanden ist (HandleAllocated=True), was ja vollkommen korrekt ist.

Ist die interne Komponente da aber noch nicht vorhanden, oder wird sie zwischendurch/danach neu erstellt, ist/wird dieses natürlich nicht gesetzt.
Darum also Dieses ebenfalls setzen, nachdem die (neu) Komponente erstellt wurde.

RWarnecke 25. Okt 2011 17:09

AW: Property Read Only bei Combobox hinzufügen (Style = csSimple)
 
Zitat:

Zitat von himitsu (Beitrag 1132366)
Hintergrund ist Folgender:
Delphi-Quellcode:
procedure TComboBoxReadOnly.SetReadOnly(Value: Boolean);
begin
  ...
  if HandleAllocated then
    SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
end;
Du setzt EM_SETREADONLY nur, wenn die interne Komponente vorhanden ist (HandleAllocated=True), was ja vollkommen korrekt ist.

Ist die interne Komponente da aber noch nicht vorhanden, oder wird sie zwischendurch/danach neu erstellt, ist/wird dieses natürlich nicht gesetzt.
Darum also Dieses ebenfalls setzen, nachdem die (neu) Komponente erstellt wurde.

Ich habe jetzt einfach die Zeile
Delphi-Quellcode:
if HandleAllocated then
einfach rausgenommen, dann habe ich die ReadOnly Funktion aktiv im Style csSimple, wenn ich den Style während der Laufzeit umstelle. Dieses war ja auch mein Ziel.

Delphi-Quellcode:
type
  TComboBoxReadOnly = class(TComboBox)
  private
    FReadOnly: Boolean;
    procedure SetReadOnly(const Value: Boolean);
   procedure KeyPress(var Key: Char);override;
   Procedure CreateWnd;Override;
  public
    { Public-Deklarationen }
  published
    property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
  end;

procedure TComboBoxReadOnly.CreateWnd;
begin
  inherited;
  ReadOnly := FReadOnly;
end;

procedure TComboBoxReadOnly.KeyPress(var Key: Char);
begin
  if not readonly then inherited;
end;

procedure TComboBoxReadOnly.SetReadOnly(const Value: Boolean);
begin
  FReadOnly := Value;
  if HandleAllocated then
    SendMessage(EditHandle, EM_SETREADONLY, Ord(Value), 0);
end;
Mit den beiden Funktionen KeyPress und CreateWnd erschlage ich doch das Gleiche, wie mit dem Weglassen der Abfrage nach HandleAllocated oder ?

Desweiteren taucht bei mir, dann auch noch die Frage auf, wenn ich jetzt das Ereignis KeyPress verwenden will in seiner ursprünglichen Form, funktioniert dieses doch nicht, da in der Deklaration ein Override drin steht ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:34 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz