Schriften unter Windows |
Für den Anfang sollte man alle Strukturen auf binär 0 setzen.
Wie einige der Windows-Strukturen braucht auch CHOOSEFONT Informationen über die eigene Größe im Feld lStructSize. Die Besetzung der Flags ist wichtig. Es gibt unter anderem an, welche Schriftarten auswählbar sind. Steht dort weder CF_SCREEN noch CF_PRINTER noch CF_BOTH, behauptet Windows, es seien keine Schriften installiert. So präpariert, startet schon einmal der Font-Dialog.
CHOOSEFONT myChooseFont = {0}; LOGFONT myLogFont = {0}; myChooseFont.lStructSize = sizeof( CHOOSEFONT ); myChooseFont.lpLogFont = &myLogFont; myChooseFont.Flags = CF_EFFECTS | CF_BOTH; if( ChooseFont( &myChooseFont ) != TRUE ) { |
Wird Flag mit CF_BOTH besetzt, liefert der Font-Dialog die Schriften, die sowohl auf dem Bildschirm als auch auf dem Drucker verfügbar sind. Allerdings muß man den Device-Kontext des Druckers dazu im hDC eingetragen haben.
Wie erhält man die korrekte Höhe? Die gewählte Punktgröße wurde in der CHOOSEFONT-Struktur beim Aufruf von ChooseFont abgelegt. Ein Punkt ist ein 72stel Zoll. Wieviele Pixel pro Zoll gedruckt werden, kann man den Druckerkontext mit Hilfe der Funktion GetDeviceCaps fragen.
Also multipliziert man senkrechte Auflösung mit Punktgröße und teilt dies durch 72. Die Funktion MulDiv erledigt dies für uns. Das Ergebnis kommt nach lfHeight im LOGFONT und nun können wir CreateFont darauf loslassen. Windows sucht sich eine passende Schrift aus und liefert ein Handle vom Typ HFONT zurück. Genau diesen erwartet später SelectObject von uns.
LONG yLogPixelsPerInch; HFONT MyFont; yLogPixelsPerInch = GetDeviceCaps(pd.hDC, LOGPIXELSY); lfTemp.lfHeight = -MulDiv(cfTemp.iPointSize/10, yLogPixelsPerInch, 72); MyFont = CreateFontIndirect( &lfTemp ); |
Der einfachste Fall des DC taucht in jedem "Hello World"-Programm auf: es ist der DC des Fensters, der von der Funktion BeginPaint geliefert wird, wenn die Fensterfunktion WM_PAINT empfangen hat.
Die Skalierung benoetigt hier eine Variable namens PunktGroesse, die an anderer Stelle ermittelt oder vorgegeben wird.
Mit der Funktion CreateFontIndirect wird aus der LOGFONT-Struktur ein Font gebildet. Das Handle HFONT wird als Rückgabewert geliefert und wird mit SelectObject an den DeviceContext (DC) gebunden.
case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT rt; GetClientRect(hWnd, &rt); // Skalierung LogFont.lfHeight = -MulDiv(PunktGroesse, GetDeviceCaps(pd.hDC, LOGPIXELSY), 72); // Font-Initialisierung HFONT Font, oldFont; Font = CreateFontIndirect(&LogFont); oldFont = (HFONT)SelectObject(hdc, Font); DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER); SelectObject(hdc, oldFont); // Font aufraeumen EndPaint(hWnd, &ps); break; |
Für den Drucker erhält man den DC beispielsweise nach dem Öffnen der Druckdialogbox.
TryPrinting(HWND hWnd) { PRINTDLG pd; DOCINFO di; CHOOSEFONT cfTemp; LOGFONT lfTemp; HFONT MyFont; char String[80]; memset(&lfTemp, '\0', sizeof(LOGFONT)); memset(&cfTemp, '\0', sizeof(CHOOSEFONT)); cfTemp.lStructSize = sizeof( CHOOSEFONT ); cfTemp.hwndOwner = hWnd; cfTemp.hDC = 0; cfTemp.lpLogFont = &lfTemp; cfTemp.Flags = CF_EFFECTS | CF_BOTH; if( ChooseFont( &cfTemp ) != TRUE ) { return 0; } memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = hWnd; pd.hDevMode = NULL; pd.hDevNames = NULL; pd.Flags = PD_RETURNDC; pd.nCopies = 1; // die DOCINFO dient der Beschreibung des Jobs fuer den Druckmanager memset(&di, 0, sizeof(DOCINFO)); di.cbSize = sizeof(DOCINFO); di.lpszDocName = "drucktest"; di.lpszOutput = NULL; // Ziel wird in Dialog ausgewählt if (PrintDlg(&pd)) { // Skalierung LONG yLogPixelsPerInch; yLogPixelsPerInch = GetDeviceCaps(pd.hDC, LOGPIXELSY); lfTemp.lfHeight = -MulDiv(cfTemp.iPointSize/10, yLogPixelsPerInch, 72); MyFont = CreateFontIndirect( &lfTemp ); SelectObject(pd.hDC, MyFont); // drucken StartDoc(pd.hDC, &di); { // Dokument wird eröffnet StartPage(pd.hDC); // Inhalt ausgeben sprintf(String, "Dies ist ein Drucktest, lfHeight: %ld", lfTemp.lfHeight); SelectObject(pd.hDC, MyFont); TextOut(pd.hDC, 70, 70, String, strlen(String)); TextOut(pd.hDC, 10, 17, String, strlen(String)); EndPage(pd.hDC); EndDoc(pd.hDC); // Dokument wird geschlossen DeleteDC(pd.hDC); } if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode); if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames); } |
Homepage - Windows-API-Programmierung | (C) Copyright 1999 Arnold Willemer |