Simple gui design problem - delphi

I have a really simple problem, but I don't find a nice way how I should solve this:
I have a TEdit field. When I enter this Edit-Field, I want to show an Panel.
When I click on the panel, the panel should hide.
When I leave the edit field, the panel also should hide, but I can't use the onExit event of the editField, because this would hide the panel before I can click it.
I'm experimenting for a while to solve this, but can't find an elegant way...
Any Ideas? thanks!

Well, that is a tricky one. Have you considered hiding the panel with the onEnter event for every control except the panel and the edit field?
In other words, the panel will not hide itself when you exit the edit field and enter the panel but it will hide itself once it has performed its work.
Exiting the edit field and entering any field other than the panel will also cause the panel to hide.
None of that is driven by the edit field onExit, more by the other fields as you enter them. It's convoluted but it may just work. See the table below for conditions and their associated actions:
onExit onEnter panelAction
------- ------- -----------
panel nothing nothing hide panel
edit field nothing show panel nothing
all others nothing hide panel nothing

You can use ActiveControl property of the Form at OnClick event of Panel and OnExit event of the EditField

actually you can use the onExit because the panel is not focuseable, so your edit is still focused when you click on the panel (tested with d7).
it's either this or i didn't understand well what you need. if the latest is the case, try rephrasing like gabr suggested earlier ;)
cheers,
G

i test your problem. check it out.
procedure TForm1.Edit1Enter(Sender: TObject);
begin
Panel1.Visible := true;
end;
procedure TForm1.Edit1MouseLeave(Sender: TObject);
begin
Panel1.Hide;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.TabStop := False;
Panel1.Visible := False;
end;
procedure TForm1.Panel1Click(Sender: TObject);
begin
(Sender as TPanel).Visible := false;
end;

Related

Displaying a disabled modal form

I'm trying to disable a TForm's descendant and showing it as a modal form.
procedure TForm1.Button1Click(Sender: TObject);
var
Frm : TMyForm;
begin
Frm := TMyForm.Create(nil);
try
Frm.Enabled := False;
Frm.ShowModal();
finally
Frm.Free;
end;
end;
At runtime, it raises the following error message:
Cannot make a visible window modal.
The OP wants to display a disabled form modally when the form should be displayed for read-only purposes.
Disabling the form is the wrong thing to do.
How do you display the information? If you are using TEdit, TMemo, or TRichEdit controls, you should simply set them to read only. Otherwise, if you have some combinations of various controls like radio buttons, you should disable each and every such control, not the form itself. I mean, surely you still want the Cancel button to be enabled?
In addition, disabling the form instead of the actual controls will make the controls look enabled, which is very confusing! That's an important point.
So what you need to do is to display the form normally (not disabled!) and then set its controls to their appropriate states when the dialog is shown.
Just to emphasise my point about disabling the form vs its controls, consider this dialog box:
If I do
procedure TCustomViewFrm.FormShow(Sender: TObject);
begin
Enabled := False;
end;
then it looks like this when shown:
As you can see, every control looks very enabled indeed, but no control responds to mouse or keyboard input. This is very confusing and a horribly bad UX.
In fact, you cannot even close the dialog box using its title-bar Close button or Alt+F4. You cannot close it using its system menu, either. In fact, you cannot close it at all, because to close a window, it must respond to user input, and a disabled window doesn't do that. (You cannot move the window, either.)
Instead, if we disable all controls (except the Cancel button),
procedure DisableControl(AControl: TWinControl);
begin
for var i := 0 to AControl.ControlCount - 1 do
begin
if
(AControl.Controls[i] is TCustomButton)
and
(TCustomButton(AControl.Controls[i]).ModalResult = mrCancel)
then
Continue;
if AControl.Controls[i] is TWinControl then
DisableControl(TWinControl(AControl.Controls[i]));
AControl.Controls[i].Enabled := False;
end;
end;
procedure TCustomViewFrm.FormShow(Sender: TObject);
begin
DisableControl(Self);
end;
you get this nice UI:
Not only is it very clear that all controls are disabled, the user can also close the dialog box without killing your application using the Task Manager.

Delphi - How to copy the text from one tedit to another, while the user is typing in the first one?

There are two tedit
One is enabled for the user, and the other disabled.
The moment user types anything in the tedit, the same thing gets typed in the disabled tedit, while the user is typing.
I don't want to use any buttons for this.
How to implement this in Delphi?
You can use the OnChange event of your first TEdit and set text of the second edit to the text of the first. This should look like
procedure TForm1.Edit1Change(Sender: TObject);
begin
Edit2.Text := Edit1.Text;
end;

entering text into an editbox; delphi

I'm trying to enter characters into an edit box by way of the user clicking buttons on a Delphi form. Button1, for example, adds to the contents of the edit box the character '1'; Button2 adds the character '2', etc.
Here is the relevant code in the event handler for each button - to take Button1 adding 1 as an example:
Edit1.text := Edit1.Text + '1';
The problem is that clicking on some buttons ensures the a number appears in the edit box while clicking on others does not, ie no number appears.
Can anyone explain what I'm doing wrong, and explain what the problem is? I'm new to all this.
Add this event handler to your form:
procedure TForm1.NumberButtonClick(Sender: TObject);
begin
Edit1.Text := Edit1.Text + (Sender as TButton).Caption;
end;
Using the Object Inspector's Events tab, set the OnClick handler of all the buttons on the panel to the above event handler.
This works perfectly in Delphi 10.1 Berlin and Delphi 2007. If it doesn't work for you, then you have something else happening and will need to post enough code for us to use to reproduce the problem.

Changing font color using TColorBox

Delphi v7
I have yet another remedial question.
Using a TColorBox I would like to change the font color in each of 4 RichEdit controls. I am using an OnClick event of the color box.
This procedure works fine for one rich edit control.
procedure TForm1.cmbFColorClick(Sender: TObject);
begin
reProc.SelAttributes.Color := cmbFColor.Selected;
end;
If I try to write the same code for each of the richedit controls it will change the font color in all of the richedit control at the same time.
Example: I select and change the text color on one richedit control, then I change the text color on a different control the text color on both richedit controls is changed at the same time.
Example
procedure TForm1.cmbFColorClick(Sender: TObject);
begin
reProc.SelAttributes.Color := cmbFColor.Selected;
reApp.SelAttributes.Color := cmbFColor.Selected;
reServ.SelAttributes.Color := cmbFColor.Selected;
end;
This procedure does not work at all
procedure TForm1.cmbFColorClick(Sender: TObject);
begin
if ActiveControl is TDBRichEdit then
with ActiveControl as TDBRichEdit do
SelAttributes.Color := cmbFColor.Selected;
end;
Is there a way I can change the text color on all of the richedit controls without affecting any of the other controls?
i think the active control is your TColorBox not the richeditboxes, because only one control can be the active control. If i remember right, this control which have the focus.
So you have to implement a procedure like this.
and you have remember by code, which was the last, active richedit.
procedure changeColor(edit : Trichedit) ;
begin
procedure changeColor(edit:Trichedit);
begin
edit.SelAttributes.Color := cmbFColor.Selected;
end;
Kind Regards
Problem solved. In a PageControl OnChange event I set the RichEdit SelLength to "0" for each rich edit control.
Thank you for your help. It gave me the idea.
I'm piecing things together from this question, your last question, the comments to those questions, and your answers to those questions.
What you are trying to do is modify SelAttributes.Color for a single rich edit control. The problem is working out which rich edit control to operate on.
Let us suppose you had the following function available:
function ActiveRichEdit: TRichEdit;
Then you could simply write:
ActiveRichEdit.SelAttributes.Color := NewColor;
Or, if there was a possibility that there was no rich edit control active:
if ActiveRichEdit<>nil then
ActiveRichEdit.SelAttributes.Color := NewColor;
So, how do we implement ActiveRichEdit? Well, it seems that you have a control with multiple pages, each containing a distinct rich edit. That sounds very much like a page control to me.
I'm going to assume that your page control is called PageControl, and the tab sheets called TabSheet1, TabSheet2 etc., and rich edit controls are named RichEdit1, RichEdit2 etc. But if your names are different then you'll need to adapt this code.
function TForm1.ActiveRichEdit: TRichEdit;
begin
if PageControl.ActivePage=TabSheet1 then
Result := RichEdit1
else if PageControl.ActivePage=TabSheet2 then
Result := RichEdit2
else if PageControl.ActivePage=TabSheet3 then
Result := RichEdit3
// etc. etc.
else
Result := nil;
end;
Now, there are other ways to do this. You could make an array of rich edit references that could be indexed by PageControl.ActivePageIndex. And there are indeed yet more possible solutions.
But the key is to use the ActivePage or ActivePageIndex properties of the page control to work out which rich edit control to operate on.

Delphi: TabStop problems of TRadioButton

When TRadioButton has TabStop=True, it's acting very strange.
If you will try to switch focus between many radio buttons on a form using Tab key, you would do it only 1 time per app session. The tabulation is one-way, never returning back to the first radio button. Also when the focus is moving across radio buttons, they becoming "checked" automatically.
Can this behavior be fixed without creating my own component?
I want standard radio buttons to
switch focus cyclically
prevent radio button from checking when the focus comes into it (I want my users to check them using Space key)
I understand that you're working with existing code, which is a real world constraint that's too often dismissed in these forums.
Sounds to me like checkboxes would suit you better. You can enforce the exclusivity normally expected of RadioButtons in the OnChecked event. That should solve your tabbing/focus and selection/deselection issues.
Checkboxes won't be checked automatically upon receiving focus, and your users can check/uncheck them with the space key.
You can put code in the OnEnter event to prevent the checkbox from selecting.
You'll need to store the previously selected RadioButton somehow though.
var
SelectedRadioButton: TRadioButton;
//event shared by all radiobuttons
procedure TForm1.RadioButton1Enter(Sender: TObject);
begin
if Sender <> SelectedRadioButton then begin
SelectedRadioButton.Checked:= true;
end;
end;
procedure TFrameOrder.RadioButton1Click(Sender: TObject);
begin
SelectedRadioButton:= (Sender as TRadioButton);
end;
procedure TFrameOrder.RadioButton1KeyPress(Sender: TObject; var Key: Char);
var
MyRadioButton: TRadioButton;
begin
MyRadioButton:= (Sender as TRadioButton);
if Key in [#32,#13] then begin
MyRadioButton.Checked:= true;
RadioButton1Click(MyRadioButton);
end; {if}
end;
It probably clearer to create a new TMyRadioButton component though because this will clutter up your regular code.
I have found an interesting article of Craig Stuntz about this problem. As I can see, I'll need to create my own control to solve it.
By default only one RadioButon has property TabStop = True;
All Radiobuttons are treated as one controll.
When radiobutton has focus you can switch beetween radiobutons using arrow up and down.
Now when user choose one option they can press tab to switch to another controll (without changing radio options).

Resources