What Uxtheme function I must use to get the default size of the minimize, Maximize and close buttons?

StackOverflow https://stackoverflow.com/questions/8776963

  •  15-04-2021
  •  | 
  •  

Question

I'm using the DrawThemeBackground function to draw some system elements on a canvas, And I need draw the title buttons of a form, the only part that i missed is how i can get the default sizes of the title buttons. Exist any Uxtheme function to get that info?

enter image description here

Was it helpful?

Solution

Looks like this is more difficult then it sounds.

First there's GetThemeMetric or GetThemeInt. But you'll see a lot of references that these functions return a 0x8007490, some "element not found", when you try to retrieve properties of caption buttons.

Then there's GetThemePartSize. This one seems to work some. That is it works ok for instance for WP_CLOSEBUTTON, but it returns nonsense for instance for WP_MINBUTTON. I would not suggest this function's use anyway since it retrieves the default dimensions of the button. If the user has changed the title size for instance, you won't get correct values. Anyway, it could be called like this:

uses
  uxtheme, themes;
...

var
  Err: HRESULT;
  Size: TSize;
begin
  Err := GetThemePartSize(ThemeServices.Theme[teWindow], 0,
                          WP_CLOSEBUTTON, CBS_NORMAL, nil, TS_TRUE, Size);

I have no idea what the former two functions would return if they worked (the dimensions of buttons for current title bar size or the default title bar size).


The only possible way to get an accurate result seems to be to use the WM_GETTITLEBARINFOEX message. But there's a drawback; it works only for Vista and up. You may need to define the message and the struct it uses depending on the Delphi version you use (D2007 here).

const
  CCHILDREN_TITLEBAR = 5;
  WM_GETTITLEBARINFOEX = $033F;

type
  tagTITLEBARINFOEX = record
    cbSize: DWORD;
    rcTitleBar: TRect;
    rgstate: array[0..CCHILDREN_TITLEBAR] of DWORD;
    rgrect: array [0..CCHILDREN_TITLEBAR] of TRect;
  end;
  TITLEBARINFOEX = tagTITLEBARINFOEX;
  TTitleBarInfoEx = tagTITLEBARINFOEX;
  PTitleBarInfoEx = ^TTitleBarInfoEx;

...

var
  TitleInfo: TTitleBarInfoEx;
begin
  SendMessage(Handle, WM_GETTITLEBARINFOEX, 0, NativeInt(@TitleInfo));

Then, you can get the size for the close button from the rect TitleInfo.rgrect[5]. See "TITLEBARINFOEX structure" for details. Notice the values are in screen coordinates.


If you need to support XP and/or below, I suggest you to use the good old GetSystemMetrics(SM_CXSIZE) and GetSystemMetrics(SM_CYSIZE) ("The width of a button in a window caption or title bar, in pixels"). You'd need to workout some approximations depending on if themes are enabled, if aero is enabled etc..

OTHER TIPS

I think SystemParametersInfo with SPI_GETNONCLIENTMETRICS is what you're looking for. I guess the minimize and maximize buttons use NONCLIENTMETRICS.iSmCaptionWidth while close uses iCaptionWidth to determine width.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top