Как определить размер части кнопки радиокнопки Windows

Я сам рисую олдскульные радиокнопки (без темы — тематические радио — это совсем другая проблема) с помощью DrawFrameControl:

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

Мне никогда не удавалось найти верный способ понять, что считать RECT. Я использовал прямоугольник 12x12, но мне бы хотелось, чтобы Windows сообщала мне размер переключателя.

DrawFrameControl, кажется, масштабирует переключатель, чтобы он соответствовал прямоугольнику, который я передаю, поэтому я должен быть близок к «правильному» размеру радио, которое выглядит не так, как другие (не нарисованные владельцем) радио на экране.

Кто-нибудь знает, как это сделать?


person Aardvark    schedule 14.09.2008    source источник


Ответы (2)


На этой странице приведены некоторые рекомендации по размеру элементов управления. Обратите внимание, что размеры указаны как в DLU (диалоговые единицы), так и в пикселях, в зависимости от того, размещаете ли вы элемент управления в диалоговом окне или нет:

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

Я думал, что GetSystemMetrics API может вернуть стандартный размер для некоторых распространенных элементов управления, но ничего не нашел. Для определения размеров может существовать общий API для конкретных элементов управления.

person Brannon    schedule 24.09.2008

Прошло некоторое время с тех пор, как я работал над этим, поэтому я описываю то, что я делал, и не обязательно прямой ответ на вопрос.

Я использую растровые изображения 13 x 13, а не 12 x 12. Похоже, что растровая часть флажка передается в WM_DRAWITEM. Однако я также настроил WM_MEASUREITEM и передал ему те же значения, поэтому мой ответ вполне может быть «Напрашивающийся вопрос» в правильном философском смысле.

        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;

Кажется, это хорошо работает как для Win2000, так и для XP, хотя я понятия не имею, что может сделать Vista.

Возможно, стоит поэкспериментировать, чтобы увидеть, что делает исключение WM_MEASUREITEM, хотя я обычно обнаруживаю, что в старом коде у меня были вполне веские причины делать что-то, что выглядит избыточным.

person David L Morris    schedule 24.09.2008