views:

20

answers:

1

I'm helping someone convert a huge mess of panels and 700 meticulously-placed checkboxes with something slightly more sane. My plan is to implement a custom control that uses the ControlPaint class to draw the checkboxes manually; this will make it easier to work with the data and dropping 700 GDI handles from the form will likely be a good thing*.

ControlPaint.DrawCheckbox() takes a Graphics, bounds for the checkbox, and a ButtonState. The bounds seemed interesting; I thought that the behavior could be either:

  • If I provide too much room, I get a checkbox drawn centered in those bounds.
  • I get a checkbox as large as the bounds I specified.

So I tested out with a 100x100 rectangle for the bounds and discovered the result is a 100x100 checkbox. Interesting! However, I just want a plain old checkbox that displays with the system's default size for a checkbox. I expected it would be a call to some API function like GetSystemMetrics(), but I'm not sure anything stands out as the right path. (Perhaps SM_CXMENUCHECK? That seems only incidentally related.)

CheckBoxRenderer renders at the right size. I'm going to use that, but I don't like not knowing how to do something. So I poked around with Reflector to see what it's doing. If you're rendering with some visual style, it calls GetThemePartSize() which is a fairly complicated API call to make but at least answers how I could get the size for a visual theme. What's interesting is if visual styles aren't being used, it seems to return a hard-coded size: 13x13. Is the system's checkbox size really hard-coded to 13 pixels square, or was this just a lazy oversight by MS?

The point of this question isn't to tell me to just use CheckBoxRenderer. I'm already doing that. I was curious how to find the size myself, and in the process of writing this used Reflector and now I'm curious if the size is actually something that can't be changed.

* I'm aware that having 700 of anything on the screen is a bad idea even if you find a way that uses negative memory. Step 2 of this project is suggesting a more sane design. DataGridView has already been dismissed as something that just didn't look right. I'm trying to take things one step at a time, and I'm also genuinely curious if there is a way to determine the system's checkbox size.

A: 

There is one fool proof method of getting the size.

1, You add an actual CheckBox instance to your Form. 2, Position it so it cannot be seen. Location = (-1000,-1000) 3, Set the check box text to whatever you want to measure. 4, Use checkBox1.GetPreferredSize(Size.Empty)

This then gives the preferred size which is the actual size needed to draw that control with the current text setting you have given it.

Phil Wright