Recent

Author Topic: [LCL Internals] How the client area is determined?  (Read 5588 times)

vm

  • Newbie
  • Posts: 6
[LCL Internals] How the client area is determined?
« on: June 27, 2016, 02:17:50 am »
Dear LCL Masters, we need your help!

Please see attached screenshot.

We've tested lazarus on ReactOS and have following issue:
All windows without menus have dirty, unpainted area in place of menu. This area is not considered as client area although it actually is.

Sample code:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. var
  3.   r: TRect;
  4. begin
  5.   r := ClientRect;
  6.   Canvas.Brush.Color := clBlue;
  7.   Canvas.FillRect(r.Left, r.Top, r.Right, r.Bottom);
  8. end;
  9.  

If I put menu component (empty) to the form the client area becomes correct.

So, which winapi/styles LCL relies on to find out whether menu exists and determine the client rect?


Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: [LCL Internals] How the client area is determined?
« Reply #1 on: June 27, 2016, 02:48:39 am »
I don't think that Lazarus is guilty. ReactOS is under development, do not expect 100% Windows functionality. I run Lazarus under Linux+Wine sometimes and it is also not 100%. For example, when I switch to other virtual desktop and back, Source Editor window is empty. I have to resize it a little to refresh the text. Also, windows with error messages are not on the top, but they are usually hidden behind the other windows.

I consider Wine or ReactOS as a temporary solution, when I need to test something, because I don't have Windows. For serious work use serious OS - Linux, BSD or real Windows.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

vm

  • Newbie
  • Posts: 6
Re: [LCL Internals] How the client area is determined?
« Reply #2 on: June 27, 2016, 02:58:35 am »

It's of course considered as ReactOS bug
https://jira.reactos.org/browse/CORE-11442

Quote
Lazarus and ReactOS will be presented for some schools in july

So we debug ReactOS :)
But is's not obvious crash - that's why we need help...
« Last Edit: June 27, 2016, 03:19:31 am by vm »

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4474
  • I like bugs.
Re: [LCL Internals] How the client area is determined?
« Reply #3 on: June 27, 2016, 09:45:11 am »
@vm, what version of Lazarus are you testing? Trunk has improvements for many things, including LCL-Win32 bindings.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

vm

  • Newbie
  • Posts: 6
Re: [LCL Internals] How the client area is determined?
« Reply #4 on: June 27, 2016, 12:27:32 pm »
I've tested lazarus-1.6.0-fpc-3.0.0-win32
Where to get later versions?

Did somebody tried lazarus under wine (not linux native) ? Is there such problem?

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4474
  • I like bugs.
Re: [LCL Internals] How the client area is determined?
« Reply #5 on: June 27, 2016, 12:48:51 pm »
I've tested lazarus-1.6.0-fpc-3.0.0-win32
Where to get later versions?

http://wiki.freepascal.org/Getting_Lazarus#Getting_Lazarus_SVN_development_version
I don't know if trunk makes a difference. It was a guess.

Quote
Did somebody tried lazarus under wine (not linux native) ? Is there such problem?

IIRC it works ok under Wine.
« Last Edit: June 27, 2016, 02:20:24 pm by JuhaManninen »
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

vm

  • Newbie
  • Posts: 6
Re: [LCL Internals] How the client area is determined?
« Reply #6 on: June 27, 2016, 01:18:14 pm »
Interesting: http://wiki.freepascal.org/ReactOS

Worked better before... :)

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: [LCL Internals] How the client area is determined?
« Reply #7 on: June 27, 2016, 06:19:52 pm »
I've tested lazarus-1.6.0-fpc-3.0.0-win32
Although I noticed a lot of instability with ReactOS and Lazarus (and the OS in general) I tried both trunk and 1.6 with FPCUP. The same problem occurs there. But it was so unstable I switched to the Lazarus 1.6 from the Application Manager. That one did work somewhat better (but still kept my project1.exe open every time).

But with some testing I came to the conclusion it is a problem in ReactOS itself.

With the following simple button1click (and default window 320x240 without menu) I get "Top=0 Bottom=240" on Windows 10.
Code: Pascal  [Select][+][-]
  1. uses Windows;
  2.  
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. var
  5.   r: TRect;
  6. begin
  7.   if Windows.GetClientRect(Self.Handle, r) then;
  8.   ShowMessage(Format('Top=%d Bottom=%d', [r.Top, r.Bottom]));
  9. end;

On ReactOS it gives "Top=0 Bottom=221".

The Windows.GetClientRect() is a simple wrapper around GetClientRect in user32.
Code: Pascal  [Select][+][-]
  1. function GetClientRect(hWnd: HWND; var lpRect: TRect): BOOL; external 'user32' name 'GetClientRect';

So there lies the fault (in ReactOS r71679, latest nightly build).

Adding an empty TMenu (so the menu isn't even visible) this function results in "Top=0 Bottom=240" in both ReactOS and Windows 10.
« Last Edit: June 27, 2016, 06:22:40 pm by rvk »

vm

  • Newbie
  • Posts: 6
Re: [LCL Internals] How the client area is determined?
« Reply #8 on: June 28, 2016, 04:44:04 am »
How does presence of TMenu affects window [styles?]?

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: [LCL Internals] How the client area is determined?
« Reply #9 on: June 28, 2016, 10:00:42 am »
How does presence of TMenu affects window [styles?]?
You're asking me ?  ;)
In Windows the ClientHeight is lowered when there is a visible TMainMenu present.
It seems ReactOS always lowers the ClientHeight (even if a TMainMenu is not present).
And when there is one present it works correctly if it is not visible.
So you need to dive in the code of ReactOS to find the place where this height is determined.
(GetClientRect() uses Wnd->rcClient.bottom so you need to find where that is set and where the TMainMenu can affect it)

It could be as simple as a mistype in { }.

For example (note: pseudocode)

Code: [Select]
Height = realheight
if TMainMenu.isPresent
  MainMenuPresent = true
  Height = Height - MenuHeight
  if not TMainMenu.isVisible
    Height = realHeight
 

Height = realheight
if TMainMenu.isPresent {
  MainMenuPresent = true
  Height = Height - MenuHeight
  if not TMainMenu.isVisible
    Height = realHeight
}

See that in the first code the { } is left out. When you do that only the MainMenuPresent line is executed for the if statement and everything below it is always executed. Something like a simple typo and wrong indentation can cause this.

You can also go back to an earlier version to see if it works there and check out what's changed in the code.
« Last Edit: June 28, 2016, 10:12:46 am by rvk »

vm

  • Newbie
  • Posts: 6
Re: [LCL Internals] How the client area is determined?
« Reply #10 on: June 28, 2016, 12:04:45 pm »
Thanks!

I've fixed it. Appeared to be in ReactOS menu drawing code

 

TinyPortal © 2005-2018