Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine the size of the button portion of a Windows radio button

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?

like image 419
Aardvark Avatar asked Sep 14 '08 23:09

Aardvark


2 Answers

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.

like image 93
Brannon Avatar answered Oct 19 '22 03:10

Brannon


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.

like image 30
David L Morris Avatar answered Oct 19 '22 03:10

David L Morris