How do I tile MDI children and maintain BorderStyle = bsNone? - delphi

I am hoping someone can help
I have created an object that has a form. I instantiate this object during runtime. The user can then instantiate a second (or multiple) object(s) via a menu step. So two child forms now exist in a parent form. Each objects form's BorderStyle is set to none and Style is set to MDIChild during form creation at runtime:
BorderStyle := bsNone;
FormStyle := fsMDIChild;
All fine. Form has no border.
Now I want to tile the two forms created. Menu > click Tile
procedure TMainForm.Tile1Click(Sender: TObject);
begin
Tile;
end;
Now the border re-appears. I need a way to get rid of the border.
I have tried stepping through the collection of objects and explicitly setting the BorderStyle to none:
procedure TMainForm.Tile1Click(Sender: TObject);
var
i: byte;
begin
Tile;
for i := 0 to GraphCollection.Count-1 do
(GraphCollection.Items[i] as TGraphForm).BorderStyle := bsNone;
end;
This does not work.
Does anyone have a workaround that retains the bsNone style after either Tile or Cascade.

You can do this in another way. I do this with Tabset (TTabSet class) without using fsMDIChild(but BorderStyle = bsNone).
You can add a tab for each form you open on TabSet. By clicking any tab, you can activate or show appropriate form. And delete the appropriate tab for any form by closing it. I prepare an example and you can get it from here.
(I miss-understand the question, my answer is about simulating MDITab for MdiChild forms when the FormStyle is fsNormal and not fsMdiChild)

Related

Procedure to change the color of multiple panels with different names in Delphi

I have a TForm with 5 TPanel controls on it. I need them to change color when they are clicked on.
I can easily write code for each TPanel to change colors, but that consists of too much code, so I was wondering if I could write a procedure to change the color of each one independently and just call this function with the name of each TPanel as a parameter? If not, then is there any other way to do this?
This is really easy.
Create a new VCL application.
Add five TPanel controls to the main form.
Select all five panels.
In the Object Inspector, set ParentBackground to False.
In the Object Inspector, click the Events tab and click the empty field to the right of the OnClick row caption. Type PanelClick and press Enter.
Write the following code:
procedure TForm1.PanelClick(Sender: TObject);
begin
if Sender is TPanel then
TPanel(Sender).Color := RGB(Random(255), Random(255), Random(255));
end;
I think this is what you asked. However, given your image, I suspect you rather would like a toggling behaviour:
procedure TForm1.PanelClick(Sender: TObject);
var
i: Integer;
begin
for i := 0 to ControlCount - 1 do
if Controls[i] is TPanel then
if Controls[i] = Sender then
TPanel(Controls[i]).Color := clHighlight
else
TPanel(Controls[i]).Color := clBtnFace;
end;
This iterates over the child controls of Self, since ControlCount and Controls mean Self.ControlCount and Self.Controls, respectively. If your target panels have a different parent (a panel, say), iterate over its children instead.
Optionally, you can give the target panels a specific Tag value (like 500) and only change the colour of such panels.
And please set BevelOuter to bvNone. We have left the 90s.

How to get to the elements on a page control?

I'm working with Delphi 7.
Suppose I have a page control on my form. This page control has two or three tabs. Each tab has a few other controls like a label, edit etc. on it. How to get, for example, to an edit's text property in the code?
Iterate across the controls of the tabsheet using its ControlCount and Controls properties.
for i := 0 to TabSheet.ControlCount-1 do
begin
if TabSheet.Controls[i] is TEdit then
ShowMessage(TEdit(TabSheet.Controls[i]).Text);
end;
This will iterate over all immediate children of the tabsheet. If you need to iterate deeper into the children of the children and so on then you want a recursive solution.
If you want to search in each tabsheet then you need to iterate over them too.
for i := 0 to PageControl.PageCount-1 do
TabSheet := PageControl.Pages[i];
for j := 0 to TabSheet.ControlCount-1 do
begin
if TabSheet.Controls[j] is TEdit then
ShowMessage(TEdit(TabSheet.Controls[j]).Text);
end;
You can still directly access the TEdit
Edit1.Text := 'My Edit box on a Tab';

How embed a firemonkey form inside a control?

I have tried to embed a form inside a Scrollbox:
procedure TfrmMain.FormCreate(Sender: TObject);
var
Control:TControlView;
begin
Control := TControlView.Create(Self);
Control.BorderIcons := [];
Control.parent := ListControls;
Control.width := 800;
ListControls.AddObject(Control);
Control.Visible:= True;
end;
However the form is displayed behind tfrmMain and outside the bouns of the form.
My idea is put a form inside a panel, and both inside scrollbox. Each form represent a complex item with several controls and stuff (the reason to not use ListBox? Firemonkey control creation is far harder than simply do a form and embed it)
The secret is in how you design your child form.
You need to create a control as a container, say a TLayout (no styling), TRectangle (Basic styling) or TPanel. I'd go with the TLayout. Decide on a name for your container, say 'Container' for the sake of argument. Now create you child form and simply assign the Parent of Container to your parent object.
So, from your code above (I'm assuming TControlView is your child form):
procedure TfrmMain.FormCreate(Sender: TObject);
var
Control:TControlView;
begin
Control := TControlView.Create(Self);
Control.Container.parent := ListControls;
Control.Container.width := 800;
end;
You have to set the container control's ClipChildren property to true.
Here is a step by step instruction:
Design your embedded form. Place a TLayout with alignment alClient onto your form. Place all controls inside this layout:
TFormEmbedded = class(TForm)
LayoutMain: TLayout;
//....
end;
Design your master form.
Place a Layout onto your master form, that shall later contain the subform.
Add the following code to FormCreate of your master form:
procedure TFormMaster.FormCreate(Sender: TObject);
var
SubForm: TFormEmbedded;
begin
SubForm := TFormEmbedded.Create(Self);
SubForm.LayoutMain.Parent := Self.LayoutSubForm;
end;
Thanks to nexial for the original description.

Delphi Modal Form Position

All the modal forms are displayed at Left Top of the screen while the setting are as Follows
BorderIcons = [biSystemMenu]
BorderStyle = bsSingle
Position = poOwnerFormCenter
Earlier it used to be display as per setting but recently i made some changes which causes the problem
Let me explain further so you can suggest appropriate solution.
My application has almost more than 50 forms and i open them as CustomerForm.Show/ShowModal.
All forms are inherited from one root form which has following code to display icon on task bar
procedure TBaseForm.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle or WS_Ex_AppWindow;
Params.WndParent := GetDesktopwindow;
end;
There was one problem that whenever a file open or file save dialog was opened from any form(whether it is modal form or not) , Main form was coming at Top, to fix this i made a Dummy Main Form and
put Application.ShowMainForm := false; in project file and this worked fine but this started all modal form appearing at Left Top Corner of the screen.
Can you please suggests on this?
As you are using the same ancestor for all your windows, you can add your own public function ShowModal with a parameter Parent: TYourForm.
In this method, you get the position of the Parent, calculate the center, and you move your modal window to its center. After, you call the real ShowModal in your own...
Add this to the create of your main form:
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or
WS_EX_TOPMOST);

Problem while using Two Forms

i don't know how to ask this question. problem is given below.
I'm using One Main form and many sub forms but not MDI Forms.
Main form Contains 5 Buttons and a Panel. each button will call a form
inside that Panel(as Parent). in that sub forms, one form(Sub3) contain TMainMenu component.
every form is working correctly while calling by clicking the buttons but, while calling the form(Sub3) the TMainMenu is not in visible. i don't know how to bring it visible.
Please help me any one.
Thanks in Advance.
Thanks & Regards,
Yuvaraj
You can only have one MainMenu on each form. While you can have multiple forms in an app each with its own MainMenu, if you show one form within another form, only the mainmenu of the "outer" form will be visible.
When you "reparent" a form to another (show formB as a "component" on formA), then you have to merge the menu's yourself as #skamradt already mentioned.
To do so, simply have your buttons use a "SwitchToForm" function like:
type
TMain_Form
...
private
FCurrentForm: TForm;
procedure SwitchToForm(showForm: TForm);
...
end;
procedure TMain_Form.SwitchToForm(showForm: TForm);
begin
if (FCurrentForm <> nil) and (FCurrentForm.Name = showForm.Name) then begin
// Naught to do
end else begin
// If a form is currently showing, hide it and if it has a menu, unmerge that
if FCurrentForm <> nil then
begin
FCurrentForm.Hide;
if Assigned(FCurrentForm.Menu) then
begin
MainMenu.UnMerge(FCurrentForm.Menu);
end;
end;
// Set the current form to the one passed in and re-parent that to the main form
// If the form has a menu, merge that with the main menu of the main form and then
// show it.
FCurrentForm := showForm;
with FCurrentForm do begin
Parent := self;
Align := alClient;
BorderIcons := [];
BorderStyle := bsNone;
end;
if Assigned(FCurrentForm.Menu) then begin
MainMenu.Merge(FCurrentForm.Menu);
end;
FCurrentForm.Show;
end;
end;
In this example: the form is parented to the main form itself, but you could of course also parent the forms to a panel or some other container on the main form.
You can use the TMainMenu.Merge and TMainMenu.Unmerge to merge/unmerge the sub-form menu with the main form menu. In your "OnActivate" for each of the child forms, I would send a custom message to the main form that would unmerge any menus from another form (which might already not be set) and merge the menu for the current form.

Resources