Как определить размер части кнопки переключателя Windows - PullRequest
8 голосов
/ 15 сентября 2008

Я рисую старую школу (без тематики - тематические радиоприемники - это еще одна проблема), переключатели самостоятельно, используя DrawFrameControl:

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 24 сентября 2008

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

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

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

2 голосов
/ 24 сентября 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, хотя я обычно обнаруживаю со старым кодом, что у меня обычно была совершенно веская причина для выполнения чего-то, что выглядит избыточным.

...