Reputation: 8043
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.
Upvotes: 1
Views: 1231
Reputation: 108948
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.
Upvotes: 4