8

I'm drawing old school (unthemed - themed radios are a whole other problem) radio buttons myself using DrawFrameControl:

DrawFrameControl(dc, &rectRadio, DFC_BUTTON, isChecked() ? DFCS_BUTTONRADIO | DFCS_CHECKED : DFCS_BUTTONRADIO);

I've never been able to figure out a sure fire way to figure out what to pass for the RECT. I've been using a 12x12 rectangle but I'de like Windows to tell me the size of a radio button.

DrawFrameControl seems to scale the radio button to fit the rect I pass so I have to be close to the "right" size of the radio looks off from other (non-owner drawn) radios on the screen.

Anyone know how to do this?

Aardvark
  • 8,474
  • 7
  • 46
  • 64

2 Answers2

4

This page shows some sizing guidelines for controls. Note that the sizes are given in both DLU (dialog units) and pixels, depending on whether you are placing the control on a dialog or not:

http://msdn.microsoft.com/en-us/library/aa511279.aspx#controlsizing

I thought the GetSystemMetrics API might return the standard size for some of the common controls, but I didn't find anything. There might be a common control specific API to determine sizing.

Brannon
  • 25,687
  • 5
  • 39
  • 44
2

It has been a while since I worked on this, so what I am describing is what I did, and not necessarily a direct answer to the question.

I happen to use bit maps 13 x 13 rather than 12 x 12. The bitmap part of the check box seems to be passed in the WM_DRAWITEM. However, I had also set up WM_MEASUREITEM and fed it the same values, so my answer may well be "Begging the question" in the correct philosophical sense.

        case WM_MEASUREITEM:
            lpmis = (LPMEASUREITEMSTRUCT) lParam;

            lpmis->itemHeight = 13;
            lpmis->itemWidth = 13;

            break;


        case WM_DRAWITEM:
            lpdis = (LPDRAWITEMSTRUCT) lParam;
            hdcMem = CreateCompatibleDC(lpdis->hDC);  



            if (lpdis->itemState & ODS_CHECKED)  // if selected
                {
                SelectObject(hdcMem, hbmChecked);
                }
            else
                {
                if (lpdis->itemState & ODS_GRAYED)
                    {
                    SelectObject(hdcMem, hbmDefault);
                    }
                else
                    {
                    SelectObject(hdcMem, hbmUnChecked);
                    }
                }
            StretchBlt(
                lpdis->hDC,         // destination DC
                lpdis->rcItem.left, // x upper left
                lpdis->rcItem.top,  // y upper left

                // The next two lines specify the width and
                // height.
                lpdis->rcItem.right - lpdis->rcItem.left,
                lpdis->rcItem.bottom - lpdis->rcItem.top,
                hdcMem,    // source device context
                0, 0,      // x and y upper left
                13,        // source bitmap width
                13,        // source bitmap height
                SRCCOPY);  // raster operation

            DeleteDC(hdcMem);
            return TRUE;

This seems to work well for both Win2000 and XP, though I have nbo idea what Vista might do.

It might be worth an experiment to see what leaving out WM_MEASUREITEM does, though I usually discover with old code that I usually had perfectly good reason for doing something that looks redundant.

David L Morris
  • 1,461
  • 1
  • 12
  • 19