![]() |
AW: VCL - spezielles Edit gesucht
Ok, nochmal die Filterung der Rücktaste in OnKeypressed eingebaut:
siehe da im Testprogramm geht es jetzt. Komisch. Jetzt mal ins richtige einbauen und wieder testen. Danke für die Hilfe! |
AW: VCL - spezielles Edit gesucht
OK, hier ist das Ergebnis meiner Bemühungen, allerdings nur oberflächlich getestet.
Für das Filtern der Eingabe gibt es drei Möglichkeiten.
MaxLength wird auf 32 initialisiert, OvertypeMode ist true by default. Wenn man OvertypeMode auf false setzt sollte man Zeichen löschen können, wie bei einem normalen Tedit, allerdings wird das Filtern angewendet.
Delphi-Quellcode:
unit PB.Vcl.FilteredEdit;
interface uses System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, Winapi.Windows, Winapi.Messages; type TPBAcceptCharEventHandler = procedure (Sender: TComponent; const aChar: Char; var Accept: boolean) of object; TPBDefaultFilter = (dfNone, dfCustom, dfHexDigits, dfDecimalDigits, dfOctalDigits); TPBCustomFilteredEdit = class(TCustomEdit) strict private FCustomFilter: TSysCharset; FDefaultFilter: TPBDefaultFilter; FOnAcceptChar: TPBAcceptCharEventHandler; FOvertypeMode: boolean; FPasteReplacesAll: boolean; strict protected function CharIsAcceptable(const aChar: Char): boolean; virtual; function ClipboardContentIsAcceptable: boolean; procedure SetCustomFilter(const Value: TSysCharset); protected procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyPress(var Key: Char); override; procedure WMCut(var Message: TWMCut); message WM_CUT; procedure WMPaste(var Message: TWMPaste); message WM_PASTE; public constructor Create(aOwner: TComponent); override; property CustomFilter: TSysCharset read FCustomFilter write SetCustomFilter; property DefaultFilter: TPBDefaultFilter read FDefaultFilter write FDefaultFilter default dfNone; property OvertypeMode: boolean read FOvertypeMode write FOvertypeMode default true; property PasteReplacesAll: boolean read FPasteReplacesAll write FPasteReplacesAll default true; property OnAcceptChar: TPBAcceptCharEventHandler read FOnAcceptChar write FOnAcceptChar; end; TPBFilteredEdit = class(TPBCustomFilteredEdit) published property Align; property Alignment; property Anchors; property AutoSize; property BevelEdges; property BevelInner; property BevelKind default bkNone; property BevelOuter; property BevelWidth; property BiDiMode; property BorderStyle; property CharCase; property Color; property Constraints; property Ctl3D; property DefaultFilter; property DoubleBuffered; property DragCursor; property DragKind; property DragMode; property Enabled; property Font; property HideSelection; property ImeMode; property ImeName; property MaxLength; property OEMConvert; property OvertypeMode; property ParentBiDiMode; property ParentColor; property ParentCtl3D; property ParentDoubleBuffered; property ParentFont; property ParentShowHint; property PopupMenu; property PasteReplacesAll; property ReadOnly; property ShowHint; property TabOrder; property TabStop; property Text; property TextHint; property Touch; property Visible; property StyleElements; property OnAcceptChar; property OnChange; property OnClick; property OnContextPopup; property OnDblClick; property OnDragDrop; property OnDragOver; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnGesture; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnMouseActivate; property OnMouseDown; property OnMouseEnter; property OnMouseLeave; property OnMouseMove; property OnMouseUp; property OnStartDock; property OnStartDrag; end; procedure Register; implementation uses Vcl.Clipbrd; const PredefinedFilters: array [TPBDefaultFilter] of TSysCharSet = ([], // dfNone [], // dfCustom ['0'..'9','A'..'F','a'..'f'], //dfHexDigits ['0'..'9'], //dfDecimalDigits, ['0'..'7'] // dfOctalDigits ); procedure Register; begin RegisterComponents('Samples', [TPBFilteredEdit]); end; constructor TPBCustomFilteredEdit.Create(aOwner: TComponent); begin inherited; // set defaults MaxLength := 32; FDefaultFilter := dfNone; FCustomFilter := []; FOvertypeMode := true; FPasteReplacesAll := true; end; function TPBCustomFilteredEdit.CharIsAcceptable(const aChar: Char): boolean; begin case DefaultFilter of dfNone : Result := true; dfCustom: Result := CharInSet(aChar, FCustomFilter); else Result := CharInSet(aChar, PredefinedFilters[DefaultFilter]); end; {case} if Assigned(FOnAcceptChar) then FOnAcceptChar(self, aChar, Result); end; function TPBCustomFilteredEdit.ClipboardContentIsAcceptable: boolean; var LLen: Integer; LText: string; I: Integer; begin Result := Clipboard.HasFormat(CF_TEXT); if Result then begin LText := Clipboard.AsText; if PasteReplacesAll then LLen := LText.Length else LLen := LText.Length + GetTextLen - SelLength; Result := LLen <= MaxLength; if Result then begin for I := Low(LText) to High(LText) do if not CharIsAcceptable(LText[I]) then begin Result := false; Break; end; {if} end; {if} end; {if} end; procedure TPBCustomFilteredEdit.KeyDown(var Key: Word; Shift: TShiftState); begin // block delete and old-style clipboard keys to simplify the logic if OvertypeMode and (Key in [VK_DELETE, VK_INSERT]) then Key := 0; inherited; end; procedure TPBCustomFilteredEdit.KeyPress(var Key: Char); begin // Ctrl-A, Ctrl-C and Ctrl-V are the only acceptable control characters! // We need those to support clipboard copy and paste and select all. if (Key < #32) and not CharInSet(Key, [^A, ^C, ^V]) then if OvertypeMode then Key := #0 else if Key <> ^H then //allow backspace if insert mode Key := #0; if (Key >= #32) and not CharIsAcceptable(Key) then Key := #0; if (Key <> #0) and OvertypeMode then begin // emulate overtype mode by selecting one character, but only if this // is not a clipboard shortcut if Key >= #32 then SelLength := 1; end; {if} inherited; end; procedure TPBCustomFilteredEdit.SetCustomFilter(const Value: TSysCharset); begin FCustomFilter := Value; if Value = [] then FDefaultFilter := dfNone else FDefaultFilter := dfCustom; end; procedure TPBCustomFilteredEdit.WMCut(var Message: TWMCut); begin // block cut to clipboard Message.Result := 0; end; procedure TPBCustomFilteredEdit.WMPaste(var Message: TWMPaste); begin if ClipboardContentIsAcceptable then begin if PasteReplacesAll then SelectAll; inherited; end; end; end. |
AW: VCL - spezielles Edit gesucht
Zitat:
An die Font Eigenschaft zum Beispiel scheine ich nicht heran zu kommen (bräuchte ich aber). Auch MaxLength kann ich so nicht erreichen, muss das aber ggf. zu Laufzeit ändern. Ok, muss mir das noch genauer anschauen, aber so passt es noch nicht zu 100% und daher frage ich mich eben, warum von einer Komponente mit weniger Möglichkeiten abgeleitet wurde. Gäbe es irgendwelche Probleme bei der Ableitung von TEdit? Geht dann was nicht richtig oder nur mit hohem Aufwand? Grüße und Danke trotzdem mal für diese Umsetzung! TurboMagick |
AW: VCL - spezielles Edit gesucht
In den Custom Controls liegt die gesamte Logik. In den "normalen" Controls werden nur die Eigenschaften veröffentlicht.
Das kann man sehen, wenn man sich den Quellcode von TCustomEdit und TEdit anschaut. Manchmal möchte man eine ganz bestimmte Eigenschaft nicht veröffentlichen, wenn der Vorgänger diese aber schon veröffentlichst hat, dann wird da nix von. |
AW: VCL - spezielles Edit gesucht
Der Unterschied von TCustomEdit und TEdit ist nur, dass bei TEdit bereits alle benötigten Properties published wurden. Das kannst du ja bei der eigens abgeleiteten Komponente noch machen.
|
AW: VCL - spezielles Edit gesucht
Zitat:
danke ja. Erst Quellcode lesen, dann hier posten ;-) Er hat da ja auch eine Klasse für drin ;-) Seine Unit funktioniert schon recht gut, ich habe aber trotzdem noch etwas verändert. Ich habe die Längenprüfung in der ClipboardContentIsAcceptable Methode ausgebaut, weil man dann an beliebiger Stelle den Clipboard Inhalt überschreibend einfügen kann, auch wenn dann ggf. ein teil davon abgeschnitten wird, weil MaxLength überschritten würde. Dafür habe ich die WM_Paste abgeändert:
Delphi-Quellcode:
Damit kann ich auch Teile des Edit textes die selektiert sind überschreiben, wobei dann
procedure TPBCustomFilteredEdit.WMPaste(var Message: TWMPaste);
begin if ClipboardContentIsAcceptable then begin if PasteReplacesAll then SelectAll else begin // This allows to select only parts of the text in the edit. That selected // part only will be replaced by the text pasted. if SelLength <= 1 then SelLength := Clipboard.AsText.Length; end; inherited; end; end; nur der selektierte Teil überschrieben wird. Man könnte überlegen, ob man diese Komponente (natürlich nach Zustimmung von Peter Below) nicht bei der JVCL einbringt. Grüße TurboMagic |
AW: VCL - spezielles Edit gesucht
Zitat:
Einfügen mittels Shift-Einf geht nicht mehr. ;-) Grüße TurboMagic |
AW: VCL - spezielles Edit gesucht
Zitat:
|
AW: VCL - spezielles Edit gesucht
Oh oh. Ich bin noch nicht alt. Bei weitem nicht. Aber ich nutze STRG+Einfg, SHIFT+Einfg und SHIFT+Delete fast ausschließlich. Selten einmal, dass ich STRG+C, STRG+V und STRG+X nutze.
Zitat:
|
AW: VCL - spezielles Edit gesucht
Zitat:
Noch etwas ist mir aufgefallen: im Kontextmenü des Edits gibt es noch AUsschneiden, das geht aber nach meinen Tests ja nicht mehr. Grüße TurboMagic |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz