关于用户界面:如何确定 Windows 单选按钮的按钮部分的大小

关于用户界面:如何确定 Windows 单选按钮的按钮部分的大小

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

我正在使用 DrawFrameControl 绘制老派(非主题 - 主题收音机是另一个问题)单选按钮:

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

我从来没有想出一个可靠的方法来确定 RECT 传递什么。我一直在使用 12x12 矩形,但我希望 Windows 告诉我单选按钮的大小。

DrawFrameControl 似乎缩放单选按钮以适合我通过的矩形,因此我必须接近收音机的"正确"尺寸,使其与屏幕上的其他(非所有者绘制的)收音机相隔。

有人知道怎么做吗?


此页面显示了一些控件的尺寸指南。请注意,大小以 DLU(对话框单位)和像素为单位给出,具体取决于您是否将控件放在对话框上:

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

我认为 GetSystemMetrics API 可能会返回一些常用控件的标准大小,但我没有找到任何东西。可能有一个通用的特定于控件的 API 来确定大小。


自从我从事此工作以来已经有一段时间了,所以我所描述的是我所做的,而不一定是对问题的直接答案。

我碰巧使用了 13 x 13 而不是 12 x 12 的位图。复选框的位图部分似乎在 WM_DRAWITEM 中传递。但是,我还设置了 WM_MEASUREITEM 并为其提供了相同的值,所以我的答案很可能是正确的哲学意义上的"乞求问题"。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
        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 会做什么,尽管我通常会发现旧代码我通常有完全的理由去做一些看起来多余的事情。


推荐阅读