问题描述
我使用 GetTextExtentPoint32()
来测量文本大小并计算组合框的宽度和高度。然而,它似乎增加了与文本量成正比的边距,我想摆脱它。似乎字符串越大,我得到的边距就越大。我如何不添加此边距?小一点是可以接受的,但请看第二张图片,右边的大空间。
对于小字符串,我觉得这个边距是可以接受的:
但是,对于大的,我会在右侧看到这个很大的空白区域,我想摆脱它:
我正在像这样测量文本大小:
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,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,300,170,hInstance,0);
while (GetMessage(&msg,NULL,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",WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,10,60,110,hwnd,(HMENU) ID_COMBO,g_hinst,NULL);
for (int i = 0; i < COUNTOF(items); i++ )
{
SendMessageW(hwndCombo,CB_ADDSTRING,(LParaM) items[i]);
}
SetDefaultFont(hwndCombo);
HWND btn1 =
CreateWindowW(L"Button",L"Click me",WS_CHILD | WS_VISIBLE,5,40,90,25,(HMENU) ID_BTN1,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,&sz));
ReleaseDC(hwndCombo,dc);
int weight = sz.cx + 10;
int height = sz.cy;
assert(SetwindowPos(hwndCombo,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);
// 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;