У меня есть строка, которая должна быть нарисована внутри прямоугольника.Установить строку внутри указанного прямоугольника
Проблема заключается в том, что иногда строка может быть слишком большой, чтобы вписаться внутрь.
Как отрегулировать размер шрифта, чтобы строка могла поместиться внутри?
Я прочитал документы для GDI
и ничего не нашел. Я до сих пор продолжаю искать в Интернете, в надежде найти что-то или получить представление о моей ...
GDI
+ вариант тоже ...
Следующий код размещен в ответ на комментарий от пользователя Jonathan Potter:
#include <windows.h>
#include <windowsx.h>
#include <CommCtrl.h>
#include <stdio.h> // swprintf_s()
#include <math.h>
#include <gdiplus.h>
#include <string>
using namespace Gdiplus;
// enable Visual Styles
#pragma comment(linker, "/manifestdependency:\"type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \
language='*'\"")
// link with Common Controls library
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "GdiPlus.lib")
//global variables
HINSTANCE hInst;
// main window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps = { 0 };
RECT rcClient = { 0 };
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rcClient);
int pageWidth = rcClient.right - rcClient.left,
pageHeight = rcClient.bottom - rcClient.top;
HFONT font = NULL, oldFont = NULL;
// target rectangle, text should fit inside
Rectangle(hdc, 0, 0, pageWidth/4, pageHeight/10);
SIZE sz;
GetTextExtentPoint32(hdc, L"This is very long string that might not fit into specified rectangle",
lstrlen(L"This is very long string that might not fit into specified rectangle"), &sz);
if (sz.cx > (pageWidth/4))
{
// get current font
LOGFONT lf;
GetObject(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
// scale it
lf.lfHeight = MulDiv(lf.lfHeight, (pageWidth/4), sz.cx);
font = CreateFontIndirect(&lf);
oldFont = SelectFont(hdc, font);
}
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255, 0, 0));
// draw text in test rectangle
RECT rcText = { 0 };
rcText.left = 0;
rcText.top = 0;
rcText.right = pageWidth/4;
rcText.bottom = pageHeight/10;
DrawTextEx(hdc,
L"This is very long string that might not fit into specified rectangle",
wcslen(L"This is very long string that might not fit into specified rectangle"),
&rcText, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOCLIP, NULL);
if (font != NULL)
{
SelectFont(hdc, oldFont);
DeleteFont(font);
}
EndPaint(hwnd, &ps);
}
return 0L;
case WM_SIZE:
{
InvalidateRect(hwnd, NULL, TRUE);
}
return 0L;
case WM_CLOSE:
::DestroyWindow(hwnd);
return 0L;
case WM_DESTROY:
{
::PostQuitMessage(0);
}
return 0L;
default:
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{
// store hInstance in global variable for later use
hInst = hInstance;
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
// register main window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"Main_Window";
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// initialize common controls
INITCOMMONCONTROLSEX iccex;
iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
iccex.dwICC = ICC_LISTVIEW_CLASSES | ICC_STANDARD_CLASSES;
InitCommonControlsEx(&iccex);
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// create main window
hwnd = CreateWindowEx(0, L"Main_Window", L"Autofit text inside rectangle",
WS_OVERLAPPEDWINDOW, 50, 50, 200, 200, NULL, NULL, hInstance, 0);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
GdiplusShutdown(gdiplusToken);
return Msg.wParam;
}
Регулировка размера шрифта на самом деле не очень хорошая идея. Фигуры рисования Windows API поддерживают обертывание и, как я помню, также «...» в конце слишком длинной строки (но, возможно, я ошибаюсь в последнем, может быть, это было только в названиях Windows). Если вы не хотите, чтобы это сокращение было обычным решением, это предоставить либо прокручивающую функциональность (используйте доступный для чтения, возможно, отключенный элемент управления редактирования), либо всплывающую подсказку или и то, и другое. Но, если вы действительно хотите, чтобы текст масштабировался, то я предлагаю рисовать его в растровом изображении в подходящем большом прямоугольнике, возможно, в два раза желаемого размера и масштабировать его. –
Измерьте строку с текущим шрифтом (например, с помощью DrawRect (DT_CALCRECT) '), определите соотношение, по которому вам нужно масштабировать размер шрифта для подходящей строки. Например. если строка в настоящее время в два раза длиннее, вам нужен шрифт в два раза меньше. –
* выяснить соотношение, по которому вам нужно масштабировать размер шрифта * Это не так просто. 'DrawTextEx' с' DT_CALCRECT' расширяет прямоугольник, когда строка не подходит, что делает мою жизнь труднее ... – AlwaysLearningNewStuff