my client requested to me for make a "effect" where each time that release any key of keyboard, change this character to asterisk on field.
How do this in Delphi?
I have in Html + Javascript like this. .js code can be found here.
There is no way to achieve what you want with the standard Delphi controls.
The VCL edit control uses the feature of the underlying Windows EDIT control to mask input characters for "Password" type edit controls. The behaviour is therefore determined by the Windows (OS) control, not Delphi itself.
You could try to get the effect you need by using a non-password field and handling key events to replace characters as required with asterisks or any other masking character, but you would also need to separately maintain the intended content of the edit control.
This would almost certainly be easier to implement as a custom edit control, rather than trying to customize the behaviour of a standard edit control with events.
I suspect that the implementation of a custom control is not the solution you are after however.
The below simulates the behavior of the js code with the difference backspace is also handled.
type
TForm2 = class(TForm)
Edit1: TEdit;
procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
private
FEditText: string;
procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = ^H then
SetLength(FEditText, Length(FEditText) - 1)
else
FEditText := FEditText + Key;
end;
procedure TForm2.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
Edit1.Text := StringOfChar('*', Length(Edit1.Text));
Edit1.SelStart := Length(Edit1.Text);
end;
FEditText is the equivalent of df[0].Value in js code, the actual value that is typed.
Note that there's no option to reset the text, as there is none in the js code.
Related
I have an abstract Delphi XE form that acts as base class for a family of forms used in my application. I am trying to figure out the best way to make a help function (on F1 keypress) that opens a wiki-page for the active form.
I'd very much like this function to be implemented at base-class level and to call when the user presses F1 but I need some advice on how to do this in a smart way. Currently I just put a KeyDown-event on the base form but this gets overwritten if the subform receives its own KeyDown, at which point I have to manually call the baseKeyDown. Obviously, this is not optimal.. Is there a way to ensure I catch the F1 keypress at baseclass level, random overloads nonwithstanding?
I am running Delphi XE on Windows 7
The straight answer to your question is that a library writer should not assign to event handlers. That's because doing so makes it hard for library consumers to also consume those events. And when you are writing a base class, you are taking the role of the library author.
So, instead of implementing the handler in the OnKeyDown event, override the KeyDown method.
type
TBaseForm = class(TForm)
protected
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
end;
....
procedure TBaseForm.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited; // this will fire the OnKeyDown event
// your processing for F1 goes here
end;
However, I wonder if you would not be better off using the built in help system. Personally I'd add an OnHelp event for the Application object and place the centralised logic there.
You should override KeyDown method in your base form class.
type
TBaseForm = class(TForm)
protected
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
end;
procedure TBaseForm.KeyDown(var Key: Word; Shift: TShiftState);
begin
// do your processing here
// ...
inherited; // call inherited method that will call OnKeyDown if assigned
end;
This is default implementation of KewDown method that calls OnKeyDown events
procedure TWinControl.KeyDown(var Key: Word; Shift: TShiftState);
begin
if Assigned(FOnKeyDown) then FOnKeyDown(Self, Key, Shift);
end;
I have a project with multiple forms that use TCombobox and i would like to remove the default behavior when a focused combobox receives a Return stroke:
In the Keydown of TCustomCombobox:
vkF4, vkReturn:
DropDown;
Q: How could i remove the functionality for all my forms?
Creating a new custom control that overrides this would mean to much work to recreate all the comboboxes.
A: Make an "imposter" subclass :
Found a Duplicate question : Delphi subclass visual component and use it
I put this code in a unit, and put that unit in the interface/uses of my forms.
TCombobox = class(FMX.ListBox.TComboBox)
protected
procedure KeyDown(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState);override;
end;
procedure TCombobox.KeyDown(var Key: Word; var KeyChar: System.WideChar;
Shift: TShiftState);
begin
if key=vkReturn then exit;
inherited;
end;
Overall idea: mimic for example, pressing the 'c' key on the keyboard while on windows desktop until you get to the 'Chrome' shortcut. Or when using a listbox, pressing the letter of the value you want instead of scrolling through the whole list. I want to be able to do this for a DBGrid, so I could press a letter to jump to the record that the first character of a string of a "name column" matches the key pressed.
This is called incremental search and in the Embarcadero CodeCentral site exist a sample of how create a DBGrid - Incremental search / filter
re your comment to RRUZ answer:
I tried to get it to work without a TEdit and gave up after several hours. I don't want to discourage you, though. I would be interested in such a solution as well. Depending on the exact use case, it might be enough to just catch the entries to the dbgrid and pass them on to an invisible TEdit which then triggers the lookup. (In my case this did not suffice.) You do this by adding a DBGrid1KeyPress method with the following code:
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
var
msg: TWMKey;
begin
msg.CharCode := Ord(KEY);
PostMessage(Edit1.Handle, WM_CHAR, Ord(key), 0);
end;
You will also have to remove doEditing from the grid's options and possibly switch it to ReadOnly.
A way to do it without having TEdit appearing on screen, is to add the following event snippets. The following code will work on top of the Embarcadero CodeCentral's code that was referred previously by RRUZ:
procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key=VK_BACK then
begin
Edit1.Text := copy(Edit1.Text,1,length(Edit1.Text)-1);
end;
end;
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if Key in ['a'..'z'] + ['A'..'Z'] then
begin
Edit1.Text := Edit1.Text + Key;
end;
end;
You can then set the Edit box invisible. All you need is to focus on the list and press keys.
I want to remove the caret from a TEdit control in Delphi. I have made the component Enabled := False but the caret still appears.
My question is how to remove the caret from a disabled TEdit control?
I assume that you mean TEdit control.
The solution is HideCaret function, the only problem is where to call it. The 2 event handlers below worked fine for me:
procedure TForm18.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
HideCaret(Edit1.Handle);
end;
procedure TForm18.Edit1MouseEnter(Sender: TObject);
begin
HideCaret(Edit1.Handle);
end;
Place a TApplicationEventscontrol on the form and in the OnIdle event, hide the caret, as follows. Set the event to nil so it only fires once.
procedure TFormMain.AppEventsIdle(Sender: TObject; var Done: Boolean);
begin
AppEvents.OnIdle := nil;
HideCaret(Memo1.Handle);
end;
why it is not possible to copy selected text in TDBMemo component into clipboard?
DELPHI 7, Windows Vista.
Following code fails to catch ctrl+c event, whereas ctrl+a works fine.
uses clipbrd;
procedure THierarchierForm.dbm1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key=Ord('A')) and (ssCtrl IN Shift) then begin
dbm1.SelectAll;
Key:=0;
end;
if (Key=Ord('C')) and (ssCtrl IN Shift) then begin
Clipboard.AsText:=dbm1.SelText;
Key:=0;
end;
end;
Thanx
The code you present works in the context of a plain vanilla form. There must be something else interfering.
The most obvious is that your form has KeyPreview set True and so your form handles CTRL+C.
Note that I stand by my reservations expressed in the comment to your question.