question

itomkucera avatar image
0 Votes"
itomkucera asked itomkucera commented

Determine checkbox square size [MFC]

Hi,

is there any way to determine the exact size of the black-bordered square of the checkbox (`CButton` with BS_AUTOCHECKBOX style) in MFC? I'm talking only about the rectangle with the black border that contains an optional checkmark. Also, I'd like to determine the width of the gap between this square and the checkbox's text.

83804-image.png

I tried everything mentioned here, but none of the answers gave me the exact result (Windows draws the 13x13px square on 100%, 16x16px on 125% dpi, 20x20px on 150%, ALSO 20x20px on 175% dpi (???), etc.). It seems that the real size doesn't seem to grow proportionally to the DPI, therefore I cannot come up with any formula. I'd also like to avoid a custom-drawn checkbox.





windows-apic++
image.png (4.5 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SongZhu-MSFT avatar image
1 Vote"
SongZhu-MSFT answered itomkucera commented

Yes, you can use GetThemePartSize function .

some code:

 HTHEME hTheme = ::OpenThemeData(hwnd, L"button");
 SIZE szCheckBox;
 HRESULT hr = GetThemePartSize(hTheme, NULL, BP_CHECKBOX, CBS_UNCHECKEDNORMAL, NULL, TS_TRUE, &szCheckBox); 
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you, so it's similar to what I tried. Passing NULL as a HDC should have no effect right? I'm not using a default system font, but size of the square shouldn't be dependent on the font right?

Also, do you know how to determine the size of the gap between the square and the text? I need to calculate this separately from the size of the square (in case the text is empty).

0 Votes 0 ·

Maybe you can refer to this answer.

0 Votes 0 ·

Thank you, this hack seems to be working on every DPI seeting.

0 Votes 0 ·
Castorix31 avatar image
1 Vote"
Castorix31 answered itomkucera commented

On which OS ?

On Windows 10 1909, I get 13*13 for the default check box size (with the usual methods : GetThemePartSize when themed or size of OBM_CHECKBOXES when not themed) and 22-23 at 175%, which is = 13*175% = 22.75

A screencopy of a (themed) CheckBox at 175% :
83875-checkbox-175.jpg




checkbox-175.jpg (11.1 KiB)
· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

GetThemePartSize looks like the function I need. It returns exactly the results I hoped for.

  auto hTheme = OpenThemeData(ctrl_->GetSafeHwnd(), L"BUTTON");
  SIZE s;
  GetThemePartSize(hTheme, dc->GetSafeHdc(), BP_CHECKBOX, CBS_CHECKEDNORMAL, NULL, TS_TRUE, &s);

Do you think this solution will work correctly at least from Win7? Does this solution look okay to you or would you change some parameters? I've never used anything like this before. Many thanks in advance.


0 Votes 0 ·

I don't know about Windows 7
I did some other tests and GetThemePartSize works for me on Windows 10 only is DPI Awareness is set (I used SetProcessDpiAwareness with PROCESS_PER_MONITOR_DPI_AWARE in a C++/Win32 test app)
If it works per default for you, maybe it is set in the Manifest (as explained at PROCESS_DPI_AWARENESS, for OS >= Windows 8.1) or initialized elsewhere




1 Vote 1 ·

Yes, it works by default, thanks for explaining this to me, I'll check out the Manifest. Can you also suggest how to determine the size of the gap between the square and the text (I need to calculate it separately from the square size, just in case the text is empty, I only need the square size, if the text is nonempty, I need the square + gap + text)? I came up with std::ceil(3 * scale_factor) formula only by testing, is there any deterministic solution (scale_factor is based on DPI, e.g. 175% DPI is 1.75)?

0 Votes 0 ·
Show more comments