Questa è la prima volta, in anni di esperienza nell'utilizzo dell'API di Windows, che mi trovo ad affrontare una situazione in cui devo fare qualcosa, che non posso, con l'attuale interfaccia di programmazione di Windows.Perché MS non ha nella sua win32api una funzione che restituisce il nome del file del font, dato l'handle del font?
Secondo la mia ricerca, il tipo di carattere "Arial Black" utilizza il file arialblk.ttf
e non c'è nessun file per il font "Arial Black Italic", nè per il font "Arial Black Bold", almeno nel mio computer con a Windows 7.
Ho inserito sotto un programma per mostrare alcune righe di testo utilizzando il carattere "Arial Black", da solo, e quindi con corsivo e grassetto. Con mia sorpresa il testo in corsivo è stato reso normalmente e il testo in grassetto è stato reso come se fosse solo "Arial Black". Poi ho capito che la stessa cosa succede con MS Word. Ho anche inserito uno screenshot di un documento Word, sovrapposto all'output del codice qui sotto. Cosa sta succedendo qui ? Devo indovinare, quale file di font viene utilizzato in ogni caso? Apparentemente l'API di Windows non mi dà la possibilità di una risposta. Perché il mistero?
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, UINT, LONG);
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
{
WNDCLASSEX wndclassx;
wndclassx.cbSize = sizeof(WNDCLASSEX);
wndclassx.style = CS_HREDRAW | CS_VREDRAW;
wndclassx.lpfnWndProc = WndProc;
wndclassx.cbClsExtra = 0;
wndclassx.cbWndExtra = 0;
wndclassx.hInstance = hInstance;
wndclassx.hIcon = nullptr;
wndclassx.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wndclassx.lpszMenuName = nullptr;
wndclassx.lpszClassName = L"WndProc";
wndclassx.hIconSm = nullptr;
if(!RegisterClassEx(&wndclassx)) return 0;
HWND hWnd = CreateWindow(L"WndProc", nullptr, WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
ShowWindow(hWnd, SW_MAXIMIZE);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
static HFONT s_hArialBlack, s_hArialBlackItalic, s_hArialBlackBold;
switch (message)
{
case WM_CREATE:
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = -MulDiv(20, 96, 72);
wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Arial Black");
if(!(s_hArialBlack = CreateFontIndirect(&lf))) return -1;
lf.lfItalic = true;
if(!(s_hArialBlackItalic = CreateFontIndirect(&lf)))
{
DeleteObject(s_hArialBlack);
return -1;
}
lf.lfWeight = FW_BOLD;
lf.lfItalic = false;
if(!(s_hArialBlackBold = CreateFontIndirect(&lf)))
{
DeleteObject(s_hArialBlackItalic);
DeleteObject(s_hArialBlack);
return -1;
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
HFONT hFont = (HFONT)SelectObject(ps.hdc, s_hArialBlack);
TextOut(ps.hdc, 20, 10, L"Font Arial Black", 16);
SelectObject(ps.hdc, s_hArialBlackItalic);
TextOut(ps.hdc, 20, 50, L"Font Arial Black Italic", 23);
SelectObject(ps.hdc, s_hArialBlackBold);
TextOut(ps.hdc, 20, 90, L"Font Arial Black Bold", 21);
SelectObject(ps.hdc, hFont);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
DeleteObject(s_hArialBlackBold);
DeleteObject(s_hArialBlackItalic);
DeleteObject(s_hArialBlack);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
Questa è la schermata di cui ho parlato sopra:
C'è un motivo per cui è necessario conoscere il nome del file del font, quando si conosce il tipo di carattere desiderato? – crashmstr
Non vorrei entrare in questo dettaglio. Ma Windows deve farlo. Ad esempio, quando un programma chiama GetFontData(), dove il primo argomento della funzione è un handle DC, Windows deve determinare il nome del file del font, in base al font selezionato nel DC. Perché tale funzione non esiste nell'API di Windows? – WaldB
È possibile che il renderer del font stia semplicemente distorcendo e addensando il font, piuttosto che usando una definizione TTF. Sono particolarmente sospettoso della versione in corsivo, ma non sono un tipo di font, quindi non posso dirlo con certezza. –