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

前端 未结 2 1278
我寻月下人不归
我寻月下人不归 2021-01-04 12:14

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 g

2条回答
  •  孤城傲影
    2021-01-04 12:39

    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..

提交回复
热议问题