Recent

Author Topic: [SOLVED] How to get the width for the size grip on TStatusBar?  (Read 1991 times)

dsiders

  • Hero Member
  • *****
  • Posts: 1282
My google-fu is weak..

I have been scouring Win32 API docs and google to find a way to get the dimensions for the size grip on a status bar. I cannot find it.

Is it a matter of getting the Text metrics for the symbol used in the Marlette(sp?) font or some other SPI_ value?

Any advice appreciated...
« Last Edit: March 02, 2024, 01:44:40 am by dsiders »
Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

440bx

  • Hero Member
  • *****
  • Posts: 4738
Re: How to get the width for the size grip on TStatusBar?
« Reply #1 on: March 01, 2024, 07:07:23 am »
Any advice appreciated...
What follows really qualifies as "any" advice, i.e, not particularly easy nor straightforward... (and in addition to that, it is likely Windows specific)

Windows determines the height of the status bar based on the vertical size of the selected font.  IOW, the size of the status bar is determined indirectly, which means that the size of its size grip is also determined indirectly and there does not seem to be a message that can be sent to the status bar to retrieve the grip size.

if you don't mind being "tricky" I believe there is a way to coerce that information out of the status bar.  The trick consists of moving the Windows cursor vertically across the status bar in the area where the size grip is.  When the cursor is over the size grip it will get a WM_NCHITTEST message. if you trap the status bar window message handler you can track the mouse coordinates that resulted in the status bar getting that message. Knowing the bottommost and topmost coordinates will allow you to calculate the grip size.  Unless the status bar is really high, it shouldn't take very many calls to SetCursorPos to figure it out.

Conceptually, that method works BUT, there is a problem when Windows is running in a VM (at least on VMware workstation), some VM software traps (VMware) the calls to SetCursorPos in a way that nullifies it, i.e, like the call never happened.  I know that for a fact because my copy of VMware does it.  I have not found a way around that problem but, maybe using SendMessage WM_MOUSEMOVE (to the status bar) instead of SetCursorPos to trigger the WM_NCHITTEST might work (I don't know I haven't tried that but, it's worth a shot.)

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

dsiders

  • Hero Member
  • *****
  • Posts: 1282
Re: How to get the width for the size grip on TStatusBar?
« Reply #2 on: March 01, 2024, 08:12:08 am »
Any advice appreciated...

What follows really qualifies as "any" advice, i.e, not particularly easy nor straightforward... (and in addition to that, it is likely Windows specific)

The question was windows-specific too. :)

Windows determines the height of the status bar based on the vertical size of the selected font.  IOW, the size of the status bar is determined indirectly, which means that the size of its size grip is also determined indirectly and there does not seem to be a message that can be sent to the status bar to retrieve the grip size.

if you don't mind being "tricky" I believe there is a way to coerce that information out of the status bar.  The trick consists of moving the Windows cursor vertically across the status bar in the area where the size grip is.  When the cursor is over the size grip it will get a WM_NCHITTEST message. if you trap the status bar window message handler you can track the mouse coordinates that resulted in the status bar getting that message. Knowing the bottommost and topmost coordinates will allow you to calculate the grip size.  Unless the status bar is really high, it shouldn't take very many calls to SetCursorPos to figure it out.

Conceptually, that method works BUT, there is a problem when Windows is running in a VM (at least on VMware workstation), some VM software traps (VMware) the calls to SetCursorPos in a way that nullifies it, i.e, like the call never happened.  I know that for a fact because my copy of VMware does it.  I have not found a way around that problem but, maybe using SendMessage WM_MOUSEMOVE (to the status bar) instead of SetCursorPos to trigger the WM_NCHITTEST might work (I don't know I haven't tried that but, it's worth a shot.)

HTH.

Thanks for that. I was hoping for something a little more mundane. ;)

I'll keep tinkering...
Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

440bx

  • Hero Member
  • *****
  • Posts: 4738
Re: How to get the width for the size grip on TStatusBar?
« Reply #3 on: March 01, 2024, 08:35:58 am »
Thanks for that. I was hoping for something a little more mundane. ;)
You're welcome and, now you know why I said it qualified as "any" ;)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

d7_2_laz

  • Hero Member
  • *****
  • Posts: 538
Re: How to get the width for the size grip on TStatusBar?
« Reply #4 on: March 01, 2024, 03:12:42 pm »
@dsiders, i think the answer would point to Windows ThemeServices (within uxtheme).
I once had a similar demand regarding the metadarkstyle component (uwin32widgetsetdark.pas here).
Accepted approach here to determine the gripsize and it's position::

Code: Pascal  [Select][+][-]
  1. gripSize: TSize;
  2. ...
  3. GetThemePartSize(TWin32ThemeServices(ThemeServices).Theme[teStatus],
  4.                  LCanvas.Handle, SP_GRIPPER, 0, @Rect, TS_DRAW, gripSize);
  5. Rect.Left:=Rect.Right - gripSize.cx;
  6. Rect.top:=Rect.Bottom - gripSize.cy;
  7.  

I’d guess that might give an idea how to apply it analogously outside this context.
Lazarus 3.6  FPC 3.2.2 Win10 64bit

dsiders

  • Hero Member
  • *****
  • Posts: 1282
Re: How to get the width for the size grip on TStatusBar?
« Reply #5 on: March 02, 2024, 01:44:13 am »
@dsiders, i think the answer would point to Windows ThemeServices (within uxtheme).
I once had a similar demand regarding the metadarkstyle component (uwin32widgetsetdark.pas here).
Accepted approach here to determine the gripsize and it's position::

Code: Pascal  [Select][+][-]
  1. gripSize: TSize;
  2. ...
  3. GetThemePartSize(TWin32ThemeServices(ThemeServices).Theme[teStatus],
  4.                  LCanvas.Handle, SP_GRIPPER, 0, @Rect, TS_DRAW, gripSize);
  5. Rect.Left:=Rect.Right - gripSize.cx;
  6. Rect.top:=Rect.Bottom - gripSize.cy;
  7.  

I’d guess that might give an idea how to apply it analogously outside this context.

I did not think of ThemeServices. Thanks  for the pointer (and the code).
Preview the next Lazarus documentation release at: https://dsiders.gitlab.io/lazdocsnext

 

TinyPortal © 2005-2018