Display TPanel as Modal - delphi

I have a main form, with multiple panels, some of which are hidden. As the user interacts with the main form, I need to make some of the hidden panels visible and display them in a modal fashion so the user can't interact with the other parts of the main form until they finish with the modal panel.
Is there a way to display an existing panel on a form in a modal fashion?
I would prefer to not cycle through the main forms controls and disable/hide everything except for the one panel, which is the common answer developers have given when others have asked this same question.
My goal is to simply display an existing panel on the main form in a modal fashion without having to manipulate the other controls on the main form.

Since a TForm has .ShowModal(), we can easily create a temporary form, move the TPanel to the form, display the form as modal, wait for the user to dismiss the form, then move the TPanel back to its original parent before destroying the TForm.
If you create a form with a hidden TPanel called pnl and a button on that panel called btnCloseModalPanel, then the following code displays pnl as modal until the user clicks the button.
begin
DisplayModalPanel(pnl);
// do something with 'pnl.data...'
end;
procedure TForm1.DisplayModalPanel(Panel: TPanel);
var
frm: TForm;
old_top, old_left: Integer;
old_parent: TWinControl;
old_visible: Boolean;
begin
frm := TForm.Create(Panel.Parent);
try
frm.BorderStyle := bsNone;
frm.Position := poOwnerFormCenter;
frm.Tag := 12921; // test in close button click, so we don't close the wrong form
// Rememer properties we can change and then restore them
old_top := Panel.Top;
old_left := Panel.Left;
old_parent := Panel.Parent;
old_visible := Panel.Visible;
// Move the panel to the modal form
Panel.Parent := frm;
Panel.Top := 0;
Panel.Left := 0;
Panel.Visible := True;
// Display the modal form
frm.AutoSize := True;
frm.ShowModal;
// Restore everything
Panel.Visible := old_visible;
Panel.Parent := old_Parent;
Panel.Left := old_left;
Panel.Top := old_top;
finally
FreeAndNil(frm);
end;
end;
procedure TForm1.btnCloseModalPanelClick(Sender: TObject);
var
frm: TForm;
begin
if pnl.Parent is TForm then
begin
frm := pnl.Parent as TForm;
if frm.Tag = 12921 then // don't close the wrong form
frm.Close;
end;
end;

Related

TEdit with clear button [duplicate]

When use TEdit control on the right side stay small icon 'x'. How after click on icon clear TEdit box.
Tnx all!
Delphi provide TClearEditButton to clear the TEdit content. It can be added by right clicking and selecting AddItem - TClearEditButton from the popup menu. It also has a Click procedure overriden in FMX.Edit unit like:
procedure TClearEditButton.Click;
var
EditTmp: TCustomEdit;
begin
inherited Click;
EditTmp := GetEdit;
if EditTmp <> nil then
begin
if EditTmp.Observers.IsObserving(TObserverMapping.EditLinkID) then
if not TLinkObservers.EditLinkEdit(EditTmp.Observers) then
Exit; // Can't change
EditTmp.Text := string.Empty;
if EditTmp.Observers.IsObserving(TObserverMapping.EditLinkID) then
TLinkObservers.EditLinkModified(EditTmp.Observers);
if EditTmp.Observers.IsObserving(TObserverMapping.ControlValueID) then
TLinkObservers.ControlValueModified(EditTmp.Observers);
end;
end;
Which make you don't need to write OnClick event handler for the TClearEditButton unless you want to do some other job along side with clearing the edit.
If you are using a TEditButton then you should write the OnClick event handler like:
procedure TForm1.EditButton1Click(Sender: TObject);
begin
Edit1.Text:= EmptyStr;
end;

How to maximize a form in a Tpanel using delphi

i'm trying to dynamically show a form in a TPanel
using this function
procedure Show_form_in_panel(form: TForm; Panel: Tpanel);
begin
form.Parent := Panel;
form.Show;
form.WindowState := wsMaximized;
end;
the form is showing very normal but he's not maximized in my panel and also i want to make this form automaticly react like components that have the Alight property = (alClient)
I want to make this form automatically react like components that have the Align property set to alClient.
That's the solution. Remove
form.WindowState := wsMaximized;
and replace with
form.Align := alClient;

Delphi - Destroy component [duplicate]

This question already has answers here:
Why does my program crash when I destroy a button in its own OnClick handler?
(3 answers)
Closed 7 years ago.
I have a problem with the following example.I have a button that creates a runtime Panel with more components:
Panel := TPanel.Create(self);
Panel.Parent := FlowPanel;
Panel.Align := alTop;
Panel.Height := 24;
Panel.Width := FlowPanel.Width;
Text := TLabel.Create(self);
Text.Parent := Panel;
Text.Align := alLeft;
Text.Caption := Query.FieldByName('Nazev').AsString;
Text.AlignWithMargins := True;
Text.Tag := Data_Id;
Text.Width := 100;
Button := TButton.Create(self);
Button.Parent := Panel;
Button.Caption := 'Odstranit';
Button.Align := alRight;
Button.Margins.Top := 0;
Button.Margins.Bottom := 0;
Button.AlignWithMargins := True;
Button.OnClick := DeleteFlowPanelItem;
Button has OnClick event on DeleteFlowPanelItem;
procedure TAdminTypyPlochy.DeleteFlowPanelItem(Sender: TObject);
var
myPanel: TPanel;
begin
myPanel := TPanel(TButton(Sender).Parent);
myPanel.Free;
end;
And when you click on that, although I component is deleted but also when it pops up message Access violation at address ... Why ?
Thanks :)
The function that calls your button OnClick event handler is a method of that same button. Your OnClick event deleted the button and so when the event handler returns, you are now executing in an instance method of an object that has been destroyed.
You need to postpone the destruction of the button until the button click event handling is complete. Use PostMessage to post a custom message that identifies which button to destroy. Handle that message by destroying the specified button. For instance the button could be passed in lParam.
Personally I'd use AllocateHWnd to create a window that can be the target for these messages. That way you can be certain to avoid problems with window re-creation.
This happens because you are freeing the button from within the button's OnClick event handler. This is simply not allowed. The button is owned by this panel, therefore, when you free the panel, it also free's this button - before its event handler finishes executing.

Forcing a Delphi form to draw when its not visible

I have a form that I scrape a bitmap to send to a small embedded TFT display. I then inject touch events from the display into the form to activate the controls. This all works very well unless the form is not visible. If its moved off the visible desktop, minimized or closed it will not get a paint event and never updates.
Is there a way to force the canvas to redraw itself visible or not?
All of the obvious things like called repaint does not work.
Yes you can use the PaintTo method on a form:
procedure TForm1.Button1Click(Sender: TObject);
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
Bitmap.Width := Form2.Width;
Bitmap.Height := Form2.Height;
Form2.PaintTo(Bitmap.Canvas, 0, 0);
Image1.Picture.Assign(Bitmap);
Bitmap.Free;
end;
Im my small example I made a project with two forms Form1 and Form2. On Form2 i placed a label and Timer.
Here's the code for Form2
procedure TForm2.Timer1Timer(Sender: TObject);
begin
Label1.Caption := FloatToStr(now);
end;
And i woks out well.

Best way to Hide and Restore an Application

I would like to hide my entire Application and then later restore it back to the state it was (Kinda like minimize to Tray).
This includes all opened forms and an included Modal Form. It should also hide each form's taskbar visibility. I can hide the MainForm, but what about the other forms and the modal form? What would be the easiest way to hide dynamically all forms and restore them back to the state how they were?
Call Application.Minimize and Application.Restore to perform these actions.
To remove a form from the taskbar, hide it. Assuming that you have Application.MainFormOnTaskbar set to True, and only the main form associated with the taskbar, you can use Application.MainForm.Visible := False. Reverse this when you call Application.Restore.
So, in summary, to go dark:
Application.Minimize;
Application.MainForm.Visible := False;
And to reappear:
Application.MainForm.Visible := True;
Application.Restore;
If you have more than one form associated with the taskbar, you'd need to hide those forms too to remove the button from the task bar.
I don't understand your question. If I remember, subforms aren't visible in taskbar. Try change forms visibility in your project options.
function HideFromTaskbar(hWnd: HWND): Boolean;
begin
if SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW) = 0 then
Result := False
else
Result := True;
end;
function HideFromTaskList(dwProcessId : DWORD) : Boolean;
const
RSP_SIMPLE_SERVICE: Integer = 1;
begin
Result := RegisterServiceProcess(dwProcessId, RSP_SIMPLE_SERVICE);
end;
ShowWindow(Application.Handle, SW_HIDE);

Resources