Centered, Full Screen Application - delphi

I am currently developing a fullscreen application that I want to be centered on the screen. I have set the following settings on the form:
WindowState:= wsMaximized
FormStyle:= fsStayOnTop
However due to the form height and width being much lower than the screens actual resolution, the form is aligned into the top-left corner. I have also attempted using the Position setting on the form, however none of these settings seem to have the desired outcome. They either have no effect or shift the entire maximized for towards the Bottom-Right corner, resulting in being able to see the forms behind (I hope I have described this well enough).
Thankyou

The way I understand your question is that the form, as such, maximises correctly, but the components are in top-left corner of the maximized form, according to their Left and Top properties as set in the form designer.
For example, a form as designed in the designer:
Form as it appears when maximized (and this is the problem):
If my understanding of the problem is correct, the solution is to place all components on a TPanel and then center that TPanel on the form.
There are two ways to center the TPanel
1) Clear (set to false) all anchors of the panel as in the link provided by TLama in his comment.
2) Center the panel in the forms OnResize event
procedure TForm4.FormResize(Sender: TObject);
begin
Panel1.Left := (ClientWidth - Panel1.Width) div 2;
Panel1.Top := (ClientHeight - Panel1.Height) div 2;
end;
Either way the result looks like:

Related

Delphi Project with custom Style

I want to create a Delphi project with a custom Style, like the below image.
As you can see, the MainForm is transparent, and there are some components inside of it.
How can I create this transparent MainForm?
P.S:I want to create VCL project and i drawn this image by Photoshop.
Assuming you're using Firemonkey since you dont specify VCL or FMX.
You don't really need to create a style for this. Rather a simpler way would be to:
Set the form transparent property to True
Place a TRectangle on the form and make it align to Most left and adjust the color etc to your liking.
Place another TRectangle on your form and set the alignment to Client. You can then adjust the Opacity property for transparency, the fill property for color and then the stroke for the border.
I see a small space between the left and right in the photo. This can be done by setting a margin left value on the second TRectangle you placed.
Now this should look like you what want it to be provided you disabled the border of the form. There is 1 more thing we need to do to avoid having the controls show as transparent. We need to place a layout on the form. Not the rectangle. If you place the controls on the rectangle with opacity the controls will also be transparent. If you want the controls to have the same transparency value place it on the rectangle. Otherwise do the following:
Place a TLayout on the form. Not the rectangle.
Set the align property to Contents. This will make it overlap everything.
Set the margin left property of the layout to the width of the left rectangle you placed + the margin value of the client rectangle you placed to compensate for the little space.
Place your controls on the layout and they should show with default opacity.
One last thing to do is implement window drag. Assuming you disabled the border, your users will not be able to move the window at all since there is no border to drag. On the MouseDown event of the component you want the drag to start add the following code:
procedure TForm1.rctngl1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Single);
begin
StartWindowDrag;
end;
You should be all done now.
EDIT: I made an example after posting this answer: FMX Semi Transparent Form

What is the difference between TScrollBar and TControlScrollBar to scroll TForm client area

I want to draw small bitmaps hold in a list on a TForm with Canvas but beyond the limit of the size of the TForm and use Vertical and Horizontal Scrollers to navigate and allow the user to display the entire area.
I noticed that there are HorzScrollBar and VertScrollBar TControlScrollBar in the TForm, but impossible to get them visible or usable, even if they are checked as Visible.
I suppose that they are concerned only with components of the TForm, if we resize the TForm, they should appear.
Do I have to use external TScrollBar (Vertical and Horizontal ones) to achieve the scrolling (by program) of the client area of the TForm or is there a way of using the HorzScrollBar and VertScrollBar TControlScrollBar?
To automatically show the scrollbars when needed (controls outside of the visible area) set AutoScroll := true;.
But that requires that you use controls to draw your images. If you want to show the scrollbars even if you only draw (paint) directly on the form canvas, you can do so by setting the Range property to the actual extent of your drawn area.
E.g.
procedure TForm24.FormCreate(Sender: TObject);
begin
self.HorzScrollBar.Range := 1000;
end;
So, to answer your question, you can use the built-in scrollbars.

Check is TScrollBox scrollbars are actually visible

I have a simple sizable form with TScrollBox (Align := alClient) and some controls put on TScrollBox. If user change the form size, TScrollBox show and hide the HorzScrollBar and VertScrollBar (depend on actual client form size).
How to check at run-time - does HorzScrollBar or VertScrollBar are visible right now?
TControlScrollBar.Visible is not an answer, because it hase a regulating function only.
Use TControlScrollBar.IsScrollBarVisible to test this.
Call IsScrollBarVisible to determine whether the scroll bar is visible. IsScrollBarVisible returns true if the Visible property is true and the associated scrolling windowed control contains child controls that lie within Margin pixels from the edge.

Why is my TScrollBox not showing scrollbars?

This seems like a very simple problem, but I cannot get a scrollbox to display scrollbars, and it is driving me crazy.
Here is the situation. I need to display a variable number of frames in a portion of a form. The area in which these frames are being displayed can be resized either through a TSplitter or by resizing the form.
I am dynamically generating the frames based on records in a database when the form is created. This frames are parented to a FlowPanel, which is responsible for frame placement. The FlowPanel is in a ScrollBox.
Due to the FlowPanel, when the user uses the TSplitter or resizes the form, the frames may re-align themselves. If any of the frames re-position out of the view of the form, I expect the ScrollBox to display scrollbars so that the user could scroll down to those inaccessible frames. This does not happen. Those frames that are in the area of the flowpanel outside the dimensions of the scrollbox are inaccessible.
I've built some tests with simple objects in a scrollbox, and the scrollbox correctly places scrollbars if any of its contained objects appear outside of the scrollbox's dimensions.
It does not matter if the flowpanel is aligned to clClient (the scrollbox) or anchored to the sides of the scrollbox, or none of these.
I realize that I can use a TPanel instead, and perform the placement and re-positioning of the frames in code from the panel's OnResize event handler, but this is what the FlowPanel is for.
What's going on here? I've fiddled around with many different scrollbox properties, and still can't get it to work. What's the issue, and is there a solution?
Ok. I am selecting Ewe's answer as correct, but the trick to making this work was in one of his comments, and I am still not completely satified with the results.
Here is the scoop. I did have my ScrollBox and FlowPanel configured the way that Ewe suggested, but played around with a number of other settings because that configuration did not work. I am pretty sure this was due to the complexity of the form's user interface, which has many panels in panels, many splitters, and the form itself is parented into a TabSheet of a PageControl (I omitted this fact since testing the form as a stand alone form produced the same results).
What made it work, albeit in a clunky fashion, is Ewe's suggestion to toggle the FlowPanel's AutoWrap off and on again. I added the following code to the OnResize event handler of the ScrollBox:
procedure TCurrentJobsForm.ScrollBox1Resize(Sender: TObject);
begin
Flowpanel1.Autowrap := False;
FlowPanel1.AutoWrap := True;
end;
There is a noticeable flicker when resizing, but I can live with that, since it produces the desired result. Once a user resizes the form, it will always be re-created using those dimensions, so resizing is something the user will do infrequently.
The ScrollBox will only show scrollbars when the containg controls exceed the visible rectangle. As the only control inside your scrollbox is the flowpanel, it doesn't help to client align the flowpanel inside the scrollbox. This will always make the flowpanel equal the size of the scrollbox and thus no scrolling is necessary.
If you want f.i. vertical scrolling, make the flowpanel top aligned and auto sized. This should make the flowpanel height bigger when more frames are placed inside.
Just in case: check that the Visible property of the vertical scrollbar is set to true.
I do not have Autosize true.
I have the flow panel on a Scrollbox.
The flow planel align is set to leftRightTopBottom.
On the formresize event I do this:
procedure TForm2.FormResize(Sender: TObject);
var
i,h:integer;
begin
h:=0;
for i:=0 to FlowPanel1.ControlCount - 1 do
h:=Max(FlowPanel1.Controls[i].BoundsRect.Bottom,h);
ScrollBox1.VertScrollBar.Range:=h;
end;
Works great.
I had similar problem and I solved it with an adaptation of #Mark's code. Considering you have a FlowPanel1 and a ScrollBox1 on your Form1, you can try:
Set the ScrollBox1's Align property to alClient;
Put the FlowPanel1 on the ScrollBox1;
Set the FlowPanel1's FlowStyle property to fsLeftRightTopBottom.
Now, on the OnResize event of the Form1, just do:
procedure TForm1.FormShow(Sender: TObject);
var
I: Integer;
VButton: TButton;
begin
for I := 1 to 10 do
begin
VButton := TButton.Create(FlowPanel1);
VButton.Parent := FlowPanel1;
VButton.Name := 'Button' + I.ToString;
VButton.Height := 200;
VButton.Width := 200;
end;
end;
See the result in the picture below:
HTH.
All efforts to get TScrollBox working failed to please but I was happy to find that dropping a TFlowPanel with AutoSize and AutoWrap set to true and its alignment set to alTop into a TPageScroller with Orientation = soVertical worked rather well. Scrolling ensued.
You may wish to embiggen the pagescroller's ButtonSize to allow it to stand out. 18 seems about right.

How to show scrollbars in TScrollBox after it has been made visible again?

I've ran into one small problem. I am dynamically generating some controls and place them on a TScrollbox component. But I noticed that if the scrollbox is visible, user can clearly see each of the controls being created and placed. So it looks like lots of work is being done and it is slow.
I hid the scrollbox and generated all the controls on it, which took much less time and no flickering and alike. But here's the problem. When I show the scrollbox again, its' scrollbar doesn't appear until I actually resize the form. (The alignment of scrollbox is alClient)
Any ideas on how to fix this?
Tried repainting, but it didn't work. Refresh didn't work either.
Thank you
EDIT:
TScrollBox(Form1.FindComponent('termai')).Visible:= false;
for I := 0 to mazgas.GrafasPagalVarda(sActiveGrafas).Termai.Count - 1 do
begin
fNaujasTermas(i,oHook);
end;
TScrollBox(Form1.FindComponent('termai')).Visible := true;
The code above shows how I hide and show the scrollbox.
fNaujasTermas generates a panel with several trackbars, images and edits.
I'm not sure about what step-by-step explanation there might be. Just make a procedure where it would generate some panel with many controls on it and set the ScrollBox as a parent. Hide scrollbox before generating anything and unhide it after all is done.
Oh btw, the panel is aligned alTop. So every time new panel is created and placed into scrollbox, it will appear at the top while all other panels will move down.
This is how I created the scrollbox itself
pTermai := TScrollBox.Create(Self);
pTermai.Parent := pLeft;
pTermai.Align := alClient;
pTermai.Name := 'termai';
pTermai.BorderStyle := bsNone;
pTermai.VertScrollBar.Increment := 40;
EDIT2: I think I know how to reproduce this.
It appears that when adding a new panel to the scrollbox, it does not count it into the total height of all the controls which already are in that scrollbox.
So to give example. Lets say 1 Panel has height of 200px.
ScrollBox height is 300px.
So after creating 2 panels which add up to 400px of height, scrollbox does not show the scrollbars, even though half of the second panel is not visible. If i add one more panel = 600px total, scrollbox will show the scrollbar which looks like it would only scroll per 2 panels, not 3. When trying to scroll such window, values get recalculated and everything is shown nicely.
So the main problem is, how to make a scrollbox show scrollbar "in time" so no panels are half cut?
You can request the scrollbox to recalculate its scrollbar properties by calling the Realign() method it inherits from TWinControl. To minimize flicker you should do this while it's still invisible, like so:
ScrollBox.Visible := False;
try
// create your new panel ...
finally
ScrollBox.Realign;
ScrollBox.Visible := True;
end;
As I said in the comments, I am unable to reproduce the problem. It would help if you gave step-by-step instructions on how to reproduce the problem.
But if you say that the problem goes away if you resize the form, why not simply resize the form? Maybe you could try to resize it 0 pixels using SetWindowPos. You might also try ScrollBox1.Perform(WM_VSCROLL, SB_PAGEUP, 0);.

Resources