I'm trying to align my child form after the main form "side by side", but have some difficulties
To reproduce the problem create new VCL application and add one button to the form:
procedure TForm1.Button1Click(Sender: TObject);
var
Form: TForm1;
begin
Application.CreateForm(TForm1, Form);
Form.BorderStyle := bsSingle;
Form.Left := Left + Width;
Form.Top := Top;
Form.Show;
end;
And result:
Windows 7:
Windows 10:
After using Winapi.DwmApi
:
DXR1 := 0;
DXL2 := 0;
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
DwmGetWindowAttribute(Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1));
Winapi.Windows.GetWindowRect(Handle, R2);
DXR1 := R2.Right - R1.Right;
DYT1 := R2.Top - R1.Top;
end;
FormJob.Left := Left + Width - DXR1;
FormJob.Top := Top - DYT1;
FormJob.Show;
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
DwmGetWindowAttribute(FormJob.Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1));
Winapi.Windows.GetWindowRect(FormJob.Handle, R2);
DXL2 := R1.Left - R2.Left;
DYT2 := R2.Top - R1.Top;
end;
FormJob.Left := FormJob.Left - DXL2;
FormJob.Top := FormJob.Top + DYT2;
And now this is completely aligned on both Windows 7 and Windows 10
Windows 7: Windows 10:
But to do that I need to show the child form first. If I call DwmGetWindowAttribute
for child (and invisible) form before showing I get the same values as for GetWindowRect
.It is impossible to get this before showing?
By dragging either the right edge, bottom edge, or the corner, you can resize the form. The second way you can resize the form while the designer is open, is through the properties pane. Select the form, then find the Properties pane in Visual Studio. Scroll down to size and expand it.
The syntax for the CSS border-width property (with 2 values) is: border-width: top_bottom left_right; When two values are provided, the first value will apply to the top and bottom of the box. The second value will apply to the left and right sides of the box.
Thanks to comment of Jonathan Potter now I have such code and it works:
var
R1, R2: TRect;
DXR1, DXL2, DYT1, DYT2: Integer;
bCloak: BOOL; // Can't use Boolean here
begin
Application.CreateForm(TFormJob, FormJob);
if (Win32MajorVersion >= 6) and DwmCompositionEnabled then begin
DXR1 := 0;
DXL2 := 0;
DYT1 := 0;
DYT2 := 0;
if (DwmGetWindowAttribute(Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1)) = S_OK) and
Winapi.Windows.GetWindowRect(Handle, R2) then begin
DXR1 := R2.Right - R1.Right; // Right width of the shadow for parent
DYT1 := R2.Top - R1.Top; // Top height of the shadow for parent
end;
bCloak := True; // Make form invisible
DwmSetWindowAttribute(FormJob.Handle, DWMWA_CLOAK, @bCloak, SizeOf(bCloak));
FormJob.Show; // Draw invisible form
if (DwmGetWindowAttribute(FormJob.Handle, DWMWA_EXTENDED_FRAME_BOUNDS, @R1, SizeOf(R1)) = S_OK) and
Winapi.Windows.GetWindowRect(FormJob.Handle, R2) then begin
DXL2 := R1.Left - R2.Left; // Left width of the shadow for child
DYT2 := R2.Top - R1.Top; // Top height of the shadow for child
end;
FormJob.Left := Left + Width - DXR1 - DXL2;
FormJob.Top := Top - DYT1 + DYT2;
bCloak := False; // Make form visible
DwmSetWindowAttribute(FormJob.Handle, DWMWA_CLOAK, @bCloak, SizeOf(bCloak));
end
else begin
FormJob.Left := Left + Width;
if FormJob.Left + FormJob.Width > Screen.DesktopRect.Right then
FormJob.Left := Screen.DesktopRect.Right - FormJob.Width;
FormJob.Top := Top;
FormJob.Show;
end;
Actually this code less readable and contain the same as original code, but this can help in the future when it is will be necessary to draw custom drawing form.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With