Forum > LCL

[SOLVED] How to query the outer size of a 'TForm' ?

(1/9) > >>

Hartmut:
When I set a size to a 'TForm' like

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Form1.Width:=200;Form1.Height:=100;then this is the inner size. The outer size of the Form is bigger, because of the Title bar and the 3 borders at the left, right and bottom side. I need these values for certain computations and because these values are different in each OS I want to query them.

I want to make a common procedure therefore in a common Unit. This means, I cannot reference to the Main Form. This is my code so far:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure queryFormOuterSize(out TitelHeight,BorderWidth: integer);   {determines the Height of the TitleBar and the Width of the left, right and    bottom Border of a 'TForm'}   var F: TForm;       P: TPoint;   begin   F:=TForm.CreateNew(nil);   F.Visible:=true; {neccessary for Windows and Linux}{$IFDEF LINUX}   Application.ProcessMessages; {neccessary for Linux only}{$ENDIF}   P:=F.ClientOrigin; {Screen coordinates of TopLeft pixel of client area of the Form}   TitelHeight:=P.y-F.Top;   BorderWidth:=P.x-F.Left;   F.Free;   end;
This works fine for the Height of the TitleBar on Win7 (24), Win10 (31) and Linux Ubuntu 22.04 (29). But this code has 3 disadvantages:

(a) the result for 'BorderWidth' is correct on Win7 and Linux (both 4), but wrong on Win10 (returns 8 instead of 1).

(b) this code needs 'F.Visible:=true' which results in a flicker.

(c) on Linux this code needs 'Application.ProcessMessages'. This can call/react to key strokes and Events and I don't want to have this in a common procedure in a common unit, where you would not expect such side affects.

Can somebody please help to avoid this disadvantages? Thanks in advance.

MarkMLl:
You cannot, in the general case do this for "a unix" since all details relating to dimensions of the "furniture" and actual placement of the window are handled by the window manager (which in practice these days is often part of the desktop environment). In short, if the hack you've got delivers adequate results use it.

Having said which, there was a recent thread on moving windows between "desktops" etc. which delved in considerable depth into the WM API, and it might be that the properties you need to query are sufficiently-well standardised that you could do something that way.

Regarding the APM, that's probably entirely down to the widget set. What you're seeing is that the Windows widget set doesn't need it, while whichever one you're using on Linux does.

MarkMLl

rvk:

--- Quote from: Hartmut on October 11, 2024, 06:44:15 pm ---When I set a size to a 'TForm' like [snip] then this is the inner size.
--- End quote ---
Is this really the case? I thought TForm.Height is the outer-size. At least it is for me on Windows.

(Although newer Windows versions can have an invisible border around the window.)

I thought TForm.ClientHeight is the inner-size.

MarkMLl:

--- Quote from: rvk on October 11, 2024, 06:59:32 pm ---Is this really the case? I thought TForm.Height is the outer-size. At least it is for me on Windows.

--- End quote ---

Fundamental difference between Windows and X11 on unix. It used to be possible to kill the window manager at which point all the furniture would disappear (without any change to the application window) and start a completely different one.

Oh, and scrollbars are traditionally part of the furniture, although I think that they might be overshadowed by controls with their own.

MarkMLl

dsiders:

--- Quote from: rvk on October 11, 2024, 06:59:32 pm ---
--- Quote from: Hartmut on October 11, 2024, 06:44:15 pm ---When I set a size to a 'TForm' like [snip] then this is the inner size.
--- End quote ---
Is this really the case? I thought TForm.Height is the outer-size. At least it is for me on Windows.

(Although newer Windows versions can have an invisible border around the window.)

I thought TForm.ClientHeight is the inner-size.

--- End quote ---

Height and Width do not reflect anything considered non-client areas - like Window titles, frames/borders, or TMainMenu. In the current LCL, ClientHeight and ClientWidth are identical to Height and Width respectively. I know... it doesn't seem right, but that's what it is.

I haven't checked on scrollbars...

Navigation

[0] Message Index

[#] Next page

Go to full version