如何从使用 GetTextExtentPoint32() 测量的文本大小中删除此边距?

how do I remove this margin from text's size measured with GetTextExtentPoint32()?

我正在使用 GetTextExtentPoint32() 测量文本大小并计算组合框的宽度和高度。但是,它似乎增加了与我要摆脱的文本量成比例的边距。似乎字符串越大,我得到的边距就越大。我怎么不添加这个保证金?一个小的是可以接受的,但看看第二张图片,右边的大空 space。

对于小字符串,我觉得这个余量可以接受:

然而,对于大的,我在右侧得到这个大的白色 space,我想摆脱它:

我是这样测量文字大小的:

              int len = wcslen(s);
              HDC dc = GetDC(hwndCombo);
              SIZE sz;
              assert(GetTextExtentPoint32(dc, s, len, &sz));
              ReleaseDC(hwndCombo, dc);
              int weight = sz.cx + 10;
              int height = sz.cy;
              assert(SetWindowPos(hwndCombo, HWND_TOP, 0, 0, weight, height, SWP_NOMOVE));

完整代码:

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "Comdlg32.lib")

#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE

#include <windows.h>
#include <winuser.h>
#include <assert.h>

#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int largestIndex();
HFONT getDefaultFont();
void SetDefaultFont(HWND hwnd);

HFONT hDefaultSystemFont;

HINSTANCE g_hinst;

const wchar_t *items[] =
{ 
  L"Windows", L"Mac", 
  L"FreeBSD", L"Arch",
  L"aaaaaa!!!!!!!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa#",
  L"foo",
  L"baaaa"
};
HWND hwndCombo;

enum
{
  ID_COMBO = 10,
  ID_BTN1,
};

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PWSTR lpCmdLine, int nCmdShow) {

    HWND hwnd;
    MSG  msg ;    
    WNDCLASSW wc = {0};
    wc.lpszClassName = L"Application";
    wc.hInstance     = hInstance ;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc   = WndProc ;
    wc.hCursor       = LoadCursor(0,IDC_ARROW);

    g_hinst = hInstance;
  
    RegisterClassW(&wc);
    hwnd = CreateWindowW(wc.lpszClassName, L"",
                  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                  100, 100, 300, 170, 0, 0, hInstance, 0);  


    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
        WPARAM wParam, LPARAM lParam) {

    switch(msg)
    {
    
        case WM_CREATE:
        {
              hwndCombo = CreateWindowW(L"Combobox", NULL, 
                    WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
                    10, 10, 60, 110, hwnd, (HMENU) ID_COMBO, g_hinst, NULL);
              for (int i = 0; i < COUNTOF(items); i++ )
              {
                SendMessageW(hwndCombo, CB_ADDSTRING, 0, (LPARAM) items[i]);
              }
              SetDefaultFont(hwndCombo);

              HWND btn1 =
              CreateWindowW(L"Button", L"Click me", 
                    WS_CHILD | WS_VISIBLE,
                    5, 40, 90, 25, hwnd, (HMENU) ID_BTN1, g_hinst, NULL); 
              SetDefaultFont(btn1);
        }
        break;

        case WM_COMMAND:
        {
          switch(LOWORD(wParam))
          {
                case ID_BTN1:
                {
                  int i = largestIndex();
                  wchar_t *s = (wchar_t*) items[i];
                  int len = wcslen(s);
                  HDC dc = GetDC(hwndCombo);
                  SIZE sz;
                  assert(GetTextExtentPoint32(dc, s, len, &sz));
                  ReleaseDC(hwndCombo, dc);
                  int weight = sz.cx + 10;
                  int height = sz.cy;
                  assert(SetWindowPos(hwndCombo, HWND_TOP, 0, 0, weight, height, SWP_NOMOVE));
                }
                break;

                default: 
                  break;
            }

        }
        break;

        case WM_DESTROY:
            DeleteObject(hDefaultSystemFont);
            hDefaultSystemFont = NULL;
            PostQuitMessage(0);
            break; 
    }
  
    return DefWindowProcW(hwnd, msg, wParam, lParam);
}

int largestIndex()
{
  int m = 0;
  int idx = -1;

  for(int i = 0; i < COUNTOF(items); i++) {
    int l = wcslen(items[i]);
    if(l > m) {
      m  = l;
      idx = i;
    }
  }

  return idx;
}



HFONT getDefaultFont()
{
  if(hDefaultSystemFont == NULL) {
    NONCLIENTMETRICS ncm;
    ncm.cbSize = sizeof(NONCLIENTMETRICS);
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
    hDefaultSystemFont = CreateFontIndirect(&ncm.lfMessageFont);
  }
  return hDefaultSystemFont;
}


void SetDefaultFont(HWND hwnd)
{
    SendMessage(hwnd, WM_SETFONT, (LPARAM) getDefaultFont(), TRUE);
}

您正在使用不同的字体进行测量。

尝试

int len = wcslen(s);
HDC dc = GetDC(hwndCombo);
SIZE sz;
// Set correct font
HFONT old = SelectObject(dc,hDefaultSystemFont);
// or
// HFONT control_font = (HFONT)SendMessage(hwndCombo, WM_GETFONT, 0, 0);
// HFONT old = SelectObject(dc,control_font);
assert(GetTextExtentPoint32(dc, s, len, &sz));
// Restore font for cleanup
SelectObject(dc,old);
ReleaseDC(hwndCombo, dc);
int weight = sz.cx + 10;
int height = sz.cy;