How to set MDI child form border to none? - forms

On my MDI Form (Parent Form), whenever I trigger a command to create a new MDI Child Form, I do these stuff (but it doesn't work):
procedure TfrmMDI.CreateChildForm(const childName: string);
var Child: TfrmChild;
begin
Child := TfrmChild.Create(Application);
Child.Caption := childName;
Child.BorderStyle := bsNone;
end;
I tried to set the Border Style of the MDI Child Form to bsNone through object inspector but it doesn't work as well.
I finally tried to set the MDI Child's Form BorderStyle through run-time however, it doesn't seemed to work too.
procedure TfrmChild.FormCreate(Sender: TObject);
begin
BorderStyle := bsNone;
end;
For additional information, my current MDI Child Form looks like this:
We may want to set our MDI Child's BS like this MDI Parent's BS:

What you are attempting to do is not how MDI is meant to be used. The GUI you want to have would likely be better served by using client-aligned TFrame objects instead of MDI child forms.

Upon waiting for some answers, I have read a documentation from Embarcadero that states:
"Changing the border style of an MDI child form to bsDialog or bsNone has no effect"
I tried to change the Application Appearance of my program to some pre-installed styles created by Embarcadero and It helped.
I just override the default style setting of my project.
Finally, it looks like this. Any border style changes will be applied to your MDI Child Form if you override the default form style:

Related

How to stop the user from change the size of the form

I have created my project to fir in a portion of the form. I disabled the buttons on the top right hand side of the form(I apologize as I don't know its technical name). I would like to also disable the user from adjust the from size via the cursor. Is that possible through code in delphi?
Set the form's BorderStyle property to bsSingle; if it isn't a dynamically generated form, you can do this using the Object Inspector. Also, I understand that you have already removed biMaximize from BorderIcons (hence, you have removed the Maximize title bar button).
I assume now that this is the main form of your application. If, on the other hand, it is a dialog box displayed when you invoke a menu item (for instance), you should instead set BorderStyle to bsDialog. Such forms are also not resizable, and they have no maximize or minimize title bar buttons).
Do the following:
Set the form's BorderIcons.biMinimize = false and BorderIcons.biMaximize = false. (As I think you already have)
Assign an event handler for the form's event OnCanResize, and code it as follows:
.
procedure TForm1.FormCanResize(Sender: TObject; var NewWidth,
NewHeight: Integer; var Resize: Boolean);
begin
Resize := False;
end;
This prevents the user from resizing the form with the mouse, while the form still has the appearance of a normal form.

Display a Form in front of another Form that is always at the top

I have a Form that stay always on top with FormStyle -> fsStayOnTop, and I did another Form with this same settings. But when I show this other Form, it is showed always behind, and not in front of first Form. So, how I do to the second Form be displayed in front of the first Form?
An owned top level window always appears above its owner. So, make the fsStayOnTop form be the owner of the other form. In VCL terms, that means setting the PopupMode property to pmExplicit, and assigning the PopupParent property.
OtherForm.PopupMode := pmExplicit;
OtherForm.PopupParent := AlwaysOnTopForm;
OtherForm.Show;

Resizing Delphi form after resizing its font in form editor

I develop a legacy Delphi 6 application, and I would like to increase the font size of one of the forms. All other forms have Microsoft Sans Serif 8pt, but this one is set to Microsoft Sans Serif 7pt. All controls have ParentFont = True, so I could simply set the font size of the form to 8pt. The problem is that the form and its controls won't resize, and the text of the labels would overlap. Is there a simple way to resize the form after resizing its font, without resizing its controls manually in the form editor?
At designtime you can effect the change by editing the .dfm file manually. Make sure that the form is saved with the Scaled property set to True.
Then, close your project in Delphi, or close Delphi altogether. Next open the .dfm file in a text editor and adjust the forms TextHeight property. For example, if you want to scale from 7pt to 8pt, and TextHeight is set to 13, then you should change it to 11. Then re-load the project and open the form in the designer and your form will be scaled. This won't be a perfect scaling because you aren't allowed floating point values for TextHeight. But it may be good enough.
At runtime, you can to call ChangeScale:
ChangeScale(NewFont.Size, OldFont.Size);
Note that ChangeScale is a protected member. So, depending on where you are calling this, you may need to use the protected member hack.
One option then would be to call the form persistence framework at runtime to generate a scaled version of the .dfm file. That would allow you more precise control than playing tricks with TextHeight
For example, you can attach the following to the OnShow event of your form:
procedure TMyForm.FormShow(Sender: TObject);
var
BinaryStream, TextStream: TStream;
begin
BinaryStream := TMemoryStream.Create;
Try
BinaryStream.WriteComponent(Self);
BinaryStream.Position := 0;
TextStream := TFileStream.Create('MyForm.dfm', fmCreate);
Try
ObjectBinaryToText(BinaryStream, TextStream);
Finally
TextStream.Free;
End;
Finally
BinaryStream.Free;
End;
end;
This will generate a new .dfm file based on the runtime state. You can then compare this with the version of the .dfm file that is in your revision control system. There will be a few changes that you won't want to accept, but mostly the changes will be the position and size changes that you do want.

Lazarus pascal/Delphi - Child form is not editable

I'm creating a new instance of a form and trying to show it as a child from on a PANEL. But The form doesn't seem to be usable. I mean I cannot edit any textbox. But there are other controls like the tree and button that seem clickable.
Here is the code:
procedure TForm1.ProcfrmSetupItemCategories;
var
NewForm: TfrmSetupItemCategories;
begin
NewForm:=TfrmSetupItemCategories.Create(BodyPanel);
NewForm.Parent := BodyPanel;
NewForm.Top:=5;
NewForm.Left:=5;
NewForm.Show;
end;
But if I remove the line NewForm.Parent := BodyPanel; the form is editable but it goes out of the parent form/Panel.
Also when the parent is set, the child form is not active (looking at the title bar)
Am I missing something? Please advice.
Thanks!
A Form needs to be a child of other forms or TApplication. The TPanel does not know how to manage forms so your form will not get activated and its components will not receive focus.
Instead you could use normal forms and write a procedure to align your forms. Now add a timer to your main form and call the alignment procedure from the ontimer event. As the user moves or resizes the main form, the other forms re-align.
Dave Peters
DP Software

Delphi Multiple MDI Children causes window state change

I'm looking to prevent MDI child WindowState changes occurring when creating a second MDI child...
I have an application that I'm developing, written in Delphi. Through a little Delphi/Windows magic, the application has multiple MDI Parents and multiple MDI Children.
I can create a form (Child A1), and maximize it within an MDI parent (Parent A). I can create a second form (Child B1) and maximize it within a second MDI parent (Parent B). Both forms will be mazimized in seperate MDI parents. So far so good. I've got this working.
However, when I create a second MDI child (Child A2) in the first MDI parent (Parent A) the WindowState (wsMaximized) of the first child (Child A1) changes when the second child (Child A2) is created. I want the first child (Child A1) to remain maximized, and the second child (Child A2) to be created and placed on top of the first child...
How can I prevent the state of the first MDI Child changing but also create a second MDI child? Any hints?
OK - Now I've had some lunch maybe I can explain it better... here's a second go at it...
The behaviour described can be reproduced in a simple MDI application (the magic I have used to create multiple MDI parents doesn't impact my problem)
Create a new forms application changing formstyle to fsMdiForm
Create a second form change its style to fsMDIChild
Create a third form change its style to fsMDIChild
Run the app. Instantiate the second form, then maximize (works as expected - maximizes in MDI Parent)
Instantiate the third form, the third form opens with window state wsNormal. But when the third form is created, the window state of the second form changes - it ceases to be maximized, and becomes wsNormal, as if you had clicked restore!
I want to avoid the restoring of the second form when I open the third form... (All forms have an initial WindowState of wsNormal...
Any hints greatly appreciated!
In my application, I also use multiple MDI Parents. Below is my magic code, where the different Childs have different states, in each Parent.
This code is adopted from: ID: 23574, Multiple MDI Parent Forms in a single Application
//Add multiple MDIForm support
TFormMDIEnhance = class(TForm)
private
_mdiClientHandle: HWND;
function GetMDIClientHandle: HWND;
protected
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure DestroyWindowHandle; override;
end;
procedure TFormMDIEnhance.CreateWindowHandle(const Params: TCreateParams);
var
mdiStruct: MDICREATESTRUCT;
begin
_mdiClientHandle := GetMDIClientHandle;
if (FormStyle = fsMDIChild) then
begin
mdiStruct.szClass := Params.WinClassName;
mdiStruct.szTitle := Params.Caption;
mdiStruct.hOwner := HInstance;
mdiStruct.x := Params.X;
mdiStruct.y := Params.Y;
mdiStruct.cx := Params.Width;
mdiStruct.cy := Params.Height;
mdiStruct.style := Params.Style;
mdiStruct.lParam := LPARAM(Params.Param);
WindowHandle := SendStructMessage(_mdiClientHandle, WM_MDICREATE, 0, mdiStruct);
Include(FFormState, fsCreatedMDIChild);
end
else
inherited CreateWindowHandle(Params);
end;
procedure TFormMDIEnhance.DestroyWindowHandle;
begin
if fsCreatedMDIChild in FFormState then
SendMessage(_mdiClientHandle, WM_MDIDESTROY, Handle, 0)
else
inherited DestroyWindowHandle;
_mdiClientHandle := 0;
end;
function TFormMDIEnhance.GetMDIClientHandle: HWND;
var
fm: TForm;
begin
result := 0;
if Owner is TForm then
begin
fm := Owner as TForm;
if Assigned(fm) then
Result := fm.ClientHandle;
end;
if (Result = 0) and Assigned(Application.MainForm) then
Result := Application.MainForm.ClientHandle;
if Result = 0 then
raise EInvalidOperation.Create(SNoMDIForm);
end;
Inherit your forms from that Base form, then you can create multiple MDI Parents.
Maybe that helps.
It's taken me ages to work out what you are really asking but I think it boils down to this comment.
I want the WindowState behaviour of the MDI children to be different in a parent. So first MDI Child is wsMax'd and the second is wsNormal.
That's not possible in MDI. When an MDI child is maximized, that is the only child window that is visible.
Remy and David are both correct in that it's an MDI limitation.
My solution in end, which does work, has been to maintain a ChildWindowState (which is just a WindowState) on each child form, then handling resizing/positioning of child windows when ChildWindowState changes... It's not a pretty answer but it does provide the functionality I needed in my application.
Thanks for all the answers :)