17 Korzystanie z czcionek


Rozdział 17
Korzystanie z czcionek
Wyświetlanie tekstu w różnych kolorach i stylach Użycie
czcionek do rozszerzania aplikacji
Od czasu wynalezienia maszyny drukarskiej przez Williama Caxtona słowo drukowane
stało się nieodłącznym elementem naszego życia. Powstała ogromna liczba krojów czcionek,
które obecnie dostępne są w niezliczonej obfitości. Właściwy wybór czcionki jest ważny dla
obrazu i stylu aplikacji. Windows wspiera wyświetlanie tekstu szerokim wachlarzem krojów i
stylów czcionek.
Funkcje rysujące tekst
Głównym zadaniem projektantów GDI Windows było opracowanie mechanizmu
wspierającego wyświetlanie wysokiej jakości grafiki przy użyciu dostępnych urządzeń.
Terminem, który zrobił furorę w latach osiemdziesiątych, jest WYSIWYG (What You See Is
What You Get). Obecnie jest on w powszechnym użyciu. Modelowanie tekstu w całym
zakresie krojów czcionek za pomocą wszelkiego rodzaju monitorów czy drukarek jest jednym
z najpoważniejszych zagadnień tego tematu. Szczęśliwie praca projektantów zakończyła się
sukcesem. Mimo szerokiego wyboru czcionek, dzięki funkcjom wyświetlania tekstu możemy
modelować tekst, mając pewność, iż otrzymają one dokładnie taką sama formę na różnych
urządzeniach.
PATRZ TAKŻE
Więcej informacji na temat kontekstów urządzeń znajdziesz w rozdziale 15.
Jak określić możliwości danego urządzenia dowiesz się w rozdziale 15.


422_______________________________ Poznaj Visual C++ 6
Inne funkcje Text0ut ()
Istnieją funkcje podobne do Text0ut (). TabbedTextOut () rozszerza tabulację w formie serii pozycji
tabulatora określonych w tablicy. PolyTextOut () wyświetla tablicę łańcuchów znakowych w jednym
wywołaniu. ExtTextOut() pozwala określać rozszerzone opcje modelowania tekstu.
Odrysowywanie prostego tekstu
Funkcja składowa kontekstu urządzenia Text0ut () jest prawdopodobnie najszybszą i najłatwiejszą
metodą rysowania tekstu. Wymaga ona podania współrzędnych x oraz y, a także wskazania obiektu
CString przechowującego treść wyświetlanego tekstu.
Posłużymy się ponownie przykładem aplikacji SDI, zawierającej pusty obszar roboczy. Utworzymy
szkielet aplikacji, korzystając z kreatora AppWizard i akceptując wszystkie opcje domyślne, jak miało to
miejsce w rozdziale 12. Użyjemy tej aplikacji do wypróbowania działania kilku funkcji rysowania
tekstu.
Otworzymy panel ClassView w widoku Project Workspace. Pośród innych ujrzymy pozycję klasy
CSimpTextView. Klikniemy umieszczony obok symbol plusa, by otworzyć listę składowych tej klasy.
Następnie klikniemy dwukrotnie pozycję OnDraw (), a do kodu implementacyjnego, otwartego w oknie
edytora, dopiszemy zawartość listingu 17.1. Linie, które wpiszemy posłużą do narysowania prostego
tekstu.
Listing 17.1. LST18_1.CPP- rysowanie tekstu przez funkcję Text0ut ()
1 void CSimpTextView::OnDraw(CDC* pDC)
2 {
3 CSimpTextDoc* pDoc = GetDocument();
4 ASSERT_VALID(pDoc) ;
5
6 // TODO: tu dodaj kod rysowania dla własnych danych
7
8 CString strText = "Water under the bridge.";
9 pDC->TextOut(100,100,strText) ; O
10 }
O Funkcja Text0ut () rysuje tekst pobrany z łańcucha w zmiennej, począwszy od punktu o
współrzędnych (100,100).


Korzystanie z czcionek 423
Na listingu 17.1 wyświetlany tekst zapisany jest w łańcuchu strText i przekazany funkcji Text0ut ()
w celu wyświetlenia na ekranie. Text0ut () również wymaga zdefiniowania współrzędnych pozycji
tekstu, która w tym przypadku określona została w linii 9 na 100 pikseli w obu osiach. Po skompilowaniu
programu ujrzymy tekst wyświetlony domyślną czcionką (czarna na białym tle), w pobliżu lewego
górnego rogu okna.
Ustalanie wyrównania tekstu
Tekst możemy ustawiać na kilka sposobów względem wyznaczonego punktu odniesienia,
korzystając z funkcji SetTextAlign (). Ta funkcja składowa kontekstu urządzenia posługuje się kilkoma
znacznikami do ustalenia wyrównania oraz sposobu ustawienia kursora po odrysowaniu tekstu.
Znaczniki wyznaczają miejsce w odniesieniu do tekstu, w którym powinien znajdować się
wyznaczony punkt. Można by sądzić, iż znacznik TA_RIGHT powoduje wyrównanie do punktu po prawej
stronie, lecz w rzeczywistości tekst zostaje wyrównany do lewej strony, mając punkt po prawej. Tabela
17.1 wymienia znaczniki, które możemy przekazać funkcji SetTextAlign () .
Ustalanie bieżącego trybu wyrównywania
Bieżące ustawienia dla kontekstu urządzenia, dotyczące wyrównywania mogą zostać zbadane za
pomocą funkcji GetTextAlign (). Zwraca ona wartość składającą się z takich samych znaczników,
jakich używa się do ustawienia wyrównywania poprzez funkcję SetTextAlign().
Tabela 17.1. Znaczniki wyrównania tekstu przekazywane funkcji SetTextAlign () Znacznik
Sposób oddziaływania na tekst
TA_LEFT Tekst wyrównany po prawej stronie punktu TA_RIGHT Tekst
wyrównany po lewej stronie punktu TA_CENTER Tekst wyśrodkowany względem
punktu TA_TOP Tekst umieszczony poniżej punktu TA_BOTTOM Tekst
umieszczony powyżej punktu TA_BASELINE Linia podstawy tekstu przechodzi
przez punkt
TAJJPDATECP po wykonaniu funkcji Text0ut () pozycja kursora graficznego zostaje uaktualniona, bez
względu na wskazane współrzędne, a nowy tekst wyświetlany jest
bezpośrednio za poprzednią pozycją
TA_NOUPDATECP Pozycja kursora graficznego nie jest uaktualniana


424_____________________________________Poznaj Visual C++ 6
Zapoznajmy się bliżej z działaniem znaczników wyrównywania rysując, krzyż w punkcie o
współrzędnych (200,200), a następnie umieszczając tekst w różnych położeniach względem niego i
przekazując odpowiednie znaczniki. Zmienimy w ten sposób treść funkcji OnDraw (), wzorując się na
listingu 17.2.
Listing 17.2. LST18_2.CPP - ustalanie wyrównania tekstu
1 void CSimpTextView::OnDraw(CDC* pDC)
2 (
3 CSimpTextDoc* pDoc = GetDocument() ;
4 ASSERT_VALID(pDoc);
5
6 // TODO: tu dodaj kod rysowania dla własnych danych
7
8 // ** Wyrównanie tekstu do prawej strony punktu
9 pDC->SetTextAlign(TA_RIGHT); O
10
11 // ** Wyświetlenie tekstu
12 pDC->TextOut(200,200,"<-Right->") ;
13
14 // ** Wyrównanie tekstu do lewej strony punktu
15 pDC->SetTextAlign(TA_LEFT) ;
16 pDC->TextOut(200,200,"<-Left->") ;
17
18 // ** Wyśrodkowanie tekstu względem punktu, leżącego poniżej tekstu
19 pDC->SetTextAlign(TA_CENTER + TA_BOTTOM); @
20 pDC->TextOut(200,200,"<-Center->") ;
21
22 pDC->MoveTo(150,200); // ** Przesuń
23 pDC->LineTo(250,200); // ** Narysuj poziomą linię
24 pDC->MoveTo(200,150); // ** Przesuń
25 pDC->LineTo(200,250); // ** Narysuj pionową linię
26
27 }
O Tekst domyślnie wyrównywany jest ze znacznikiem RIGHT, lecz użyto go tutaj dla zwiększenia
przejrzystości.
Znaczniki mogą być łączone według potrzeb. W tym przypadku tekst jest wy-środkowany i
umieszczony powyżej wyznaczonego punktu odniesienia.


Korzystanie z czcionek 425
Każde wywołanie Text0ut () odnosi się do tych samych współrzędnych, lecz tekst pojawia
się w różnych pozycjach. Jeśli skompilujemy i uruchomimy program, naszym oczom ukaże się
widok jak na rysunku 17.1.
gle Edit Mew Usip ..^
<-L< ft->
<-Right-X-Left->
Rysunek 17.1. Różne warianty wyrównania tekstu
PATRZ TAKŻE
Szczegóły dotyczące rysowania linii i figur znajdziesz w rozdziale 16.
Zmiana koloru czcionki i jej tła
Domyślnie czcionki wyświetlane są w czarnym kolorze na białym tle - możemy to jednak zmienić w
kontekście urządzenia za pomocą dwóch funkcji, SetTextColor () oraz SetBkColor (). Obie funkcje
pobierają tylko jeden parametr, czyli wartość COLORREF żądanego koloru dla czcionki lub tła. Zwracają
one również wartości COLORREF, określające kolory użyte poprzednio.
Sprawdzanie bieżących kolorów tekstu
Bieżące kolory użyte w tekście można zbadać za pomocą funkcji GetTextColor() oraz GetBkColor (),
które zwracają wartości kolorów czcionki i tła. Wartości podawane są w postaci COLORREF.


426_____________________________________Poznaj Visual C++ 6
Wykorzystajmy te funkcje do zmiany koloni czcionki i tła poprzez dopisanie do implementacji
OnDraw() wywołań funkcji, przed wywołaniem Text0ut (). Możemy posłużyć się w tym celu listingiem
17.3.
Listing 17.3. LST18_3.CPP - ustalenie kolorów za pomocą funkcji SetTextColor () oraz SetBkColorO
1 // ** Wybór niebieskiego koloru dla czcionki
2 pDC->SetTextColor(RGB(O,O,255)) ;
3 pDC->TextOut(200,200,"<-Right->") ;
4
5 pDC->SetTextAlign(TA_LEFT);
6
7 // ** Wybór czerwonego koloru dla czcionki
8 pDC->SetTextColor(RGB(255,0,0)); O
9 pDC->TextOut(200,200,"<-Left->") ;
10
11 // Punkt odniesienia pośrodku i poniżej tekstu
12 pDC->SetTextAlign(TA_CENTER + TA_BOTTOM);
13
14 // ** Wybór żółtego koloru dla czcionki
15 pDC->SetTextColor(RGB(255,255, 0) ) ;
16
17 // ** Wybór ciemnoniebieskiego koloru dla tlą
18 pDC->SetBkColor(RGB(0,0,128) ) ; @
19 pDC->TextOut(200,200,"<-Center->") ;
O Ta linia ustala kolor czcionki, którym ma zostać narysowana. @ Ta linia
ustala kolor tła.
Na powyższym listingu funkcja SetTextOut () wywołana w linii 2 zmienia kolor tekstu na niebieski,
linia 8 na czerwony, a linia 15 na żółty. W linii 18 następuje zmiana koloru tła na ciemnoniebieski.
Po skompilowaniu i uruchomieniu programu zobaczymy te same napisy, co poprzednio lecz w
różnych kolorach.
PATRZ TAKŻE
Więcej informacji na temat wyboru kolorów i makra RGB znajdziesz w rozdziale 16.


Korzystanie z czcionek 427
Rysowanie tekstu przezroczystego i nieprzezroczystego
Rysowany tekst zwykle przesłania obszar pod nim umieszczony. Czasami jednak zachodzi potrzeba
zlania tekstu z rysunkiem. Funkcja SetBkMode () umożliwia przełączanie pomiędzy dwoma trybami.
Pobiera jeden parametr, będący znacznikiem żądanego trybu. Dostępne tryby to domyślny OPAQUE oraz
TRANSPARENT (dla tekstu z przezroczystym tłem). Jeśli wywołamy funkcję SetBkMode () ze znacznikiem
OPAQUE, do narysowania tekstu użyte zostaną oba wybrane kolory, czcionki i tła. Podczas rysowania w
trybie TRANSPARENT użyty zostanie tylko kolor czcionki.
Aby zademonstrować działanie tych trybów, wprowadzimy zgodnie z listingiem 17.4 modyfikacje
funkcji OnDraw ().
Listing 17.4. LST18_4.CPP - ustalanie trybów TRANSPARENT i OPAQUE
1 void CSimpTextView::OnDraw(CDC* pDC)
2 (
3 CSimpTextDoc* pDoc = GetDocument();
4 ASSERT_VALID(pDoc) ;
5
6 // TODO: tu dodaj kod rysowania dla własnych danych 1
8 pDC->Ellipse(160,160,240,240) ;
9 pDC->SetTextAlign(TA_CENTER) ;
10
11 // ** Wybranie trybu Transparent
12 pDC->SetBkMode(TRANSPARENT);
13
14 // ** Wyświetlenie tekstu
15 pDC->TextOut(200, 180, "Transparent"); O
16
17 // ** Wybranie trybu Opaque
18 pDC->SetBkMode(OPAQUE); @
19
20 // ** Wy s wie t Jen-i e tekstu
21 pDC->TextOut(200, 220, "Opaque");
22 }
O W trybie TRANSPARENT okrąg widoczny jest pod napisem. @ W trybie OPAQUE tekst jest
rysowany wraz z tłem przesłaniającym okrąg.


428_____________________________________Poznaj Visual C++ 6
Na powyższym listingu każdy tekst wyświetlany za linią 12 będzie posiadał przezroczyste tto. W
linii 18 następuje zmiana trybu na OPAQUE, co powoduje rysowanie tła nieprzezroczystego.
Jeśli skompilujemy i uruchomimy program zawierający opisane modyfikacje zobaczymy, że
powierzchnia okręgu jest przesłonięta tłem napisu Opaque. W przypadku napisu Transparent, okrąg nie
jest przesłaniany jego tłem. Ustalony jest kolor tła nie jest brany pod uwagę podczas rysowania w trybie
TRANSPARENT.
Obcinanie tekstu
Często zachodzi potrzeba obcięcia tekstu nie mieszczącego się w wyznaczonym prostokącie. Mimo
iż możemy dokonać brutalnego cięcia, rozsądniejszym rozwiązaniem jest umożliwienie tekstowi
wypłynięcie poza wyznaczony obszar.
Użycie znacznika TA UPDATECP w funkcji ExtTextOut ()
Znacznik wyrównania tekstu TA_UPDATECP może być użyty przez funkcję setAli-gnText () w
połączeniu z ExtTextOut (). Gdy znacznik ten jest ustawiony, współrzędne pobierane w pierwszym
wywołaniu Text0ut () lub ExtTextOut () są wykorzystywane w zwykły sposób. Kolejne wywołania
jednakże ignorują podane współrzędne i rysują tekst za bieżącą pozycją kursora.
Funkcja ExtTextOut () jest bardziej wyrafinowana niż Text0ut (). Przekazując jej znacznik
ETO_CLIPPED powodujemy obcięcie tekstu. ExtTextOut (), podobnie jak Text0ut () pobiera jako dwa
pierwsze parametry współrzędne x oraz y. Jako trzeci parametr podawać możemy znaczniki, takie jak
ETO_CLIPPED. Możemy również połączyć znaczniki ETO_CLIPPED oraz ETO_OPAQUE, co pozwoli użyć
tekstu nieprzezroczystego, nawet jeśli ustawiony jest tryb TRANSPARENT. Jeśli nie życzymy sobie
obcinania ani nie-przezroczystości tekstu, jako trzeci parametr podajemy wartość zero (jak w linii 13
listingu 17.5). Czwarty parametr wymaga obiektu CRect i jeśli ustawiony jest znacznik obcinania,
obcinanie wykonane zostanie równo z krawędziami prostokąta. Piątym parametrem jest treść
wyświetlanego tekstu umieszczona w obiekcie CString. Na koniec, jako szósty parametr przekazujemy
tablicę odstępów międzyznakowych lub wybieramy odstępy domyślne, przekazując wartość NULL.
Dokonamy teraz kolejnej modyfikacji treści OnDraw, według listingu 17.5. Listing 17.5.
LST18_5.CPP - obcinanie tekstu przez funkcję ExtTextOut ()
1 void CSimpTextView::OnDraw(CDC* pDC)
2 (
3 CSimpTextDoc* pDoc = GetDocument() ;
4 ASSERT_VALID(pDoc);


5
6 // TODO: tu dodaj kod rysowania dla własnych danych
7
8 CRect rcClipBox(CPoint(100,100),CPoint(250,120));
9 pDC->Rectangle(rcClipBox);
10 pDC->SetBkMode(TRANSPARENT) ;
11
12 // ** Tekst nieobcięty
13 pDC->ExtTextOut(100,100,O,rcClipBox,
14 _"This text won't fit in there!",NULL);
15
16 rcClipBox.OffsetRect(O,40);
17 pDC->Rectangle(rcClipBox);
18
19 // ** Tekst obcięty
20 pDC->ExtTextdut(100,140,ETO_CLIPPED ,rcClipBox, O
21 _"This text won't fit in there!",NULL);
22 }
O Funkcja ExtTextOut() obcina tekst wewnątrz wyznaczonego prostokąta, o ile przekazano znacznik
ETO_CLIPPED.
W linii 8 powyższego listingu zadeklarowany zostaje prostokąt. Będzie on użyty do
pozycjonowania i obcięcia tekstu. Wywołana w linii 13 funkcja ExtTextOut () nie posiada znacznika
ETO_CLIPPED, w związku z czym tekst wylewa się poza obszar prostokąta. Drugie wywołanie funkcji w
linii 20 posiada ten znacznik i dlatego tekst będzie obcięty wewnątrz prostokąta.
Po skompilowaniu i uruchomieniu programu zobaczymy dwa prostokąty. Pierwszy będzie zawierał
tekst wylewający się na zewnątrz, w drugim natomiast ten sam tekst zostanie obcięty.
PATRZ TAKŻE
Szczegółów na temat rysowania i obcinania szukaj w rozdziale 15.
Tworzenie czcionek
Jak dotąd, tekst wyświetlany był przy użyciu domyślnej czcionki kontekstu urządzenia. Podobnie
jak pędzle i pióra, czcionki również reprezentowane są przez obiekty GDI i mogą być umieszczane oraz
usuwane z kontekstu urządzenia. Czcionki możemy tworzyć


430_____________________________________Poznaj Visual C++ 6
korzystając z różnych funkcji dostarczanych przez GDI Windows oraz klas osłonowych MFC.
Stosowanie klasy CFont
CFont jest klasą osłonową dla obiektów GDI czcionek. Inaczej niż niektóre klasy osłonowe, CFont
nie może być konstruowana z ustawieniami domyślnymi. Musimy zadeklarować obiekt CFont, a
następnie użyć jednej spośród funkcji Create dla określenia wielu możliwych parametrów.
Funkcje Create nie zawsze są w stanie dostarczyć czcionki zgodnej z oczekiwaniami. Wtedy
program zarządzający czcionkami stara się znaleźć czcionkę najbardziej zbliżoną do żądanej (zwykle
wywiązując się z zadania całkiem dobrze).
Tworzenie czcionek za pomocą funkcji CreatePointFont()
Zastosowanie funkcji CreatePointFont () jest najłatwiejszym sposobem tworzenia czcionek. Funkcja
ta wymaga trzech parametrów: rozmiaru czcionki podanego w dziesiątych częściach punktu, nazwy kroju
czcionki (na przykład Arial) oraz wskazania kontekstu urządzenia, w którym czcionka ma zostać
umieszczona. Posługując się listingiem 17.6 zmodyfikujmy treść OnDraw (), w wyniku czego
wyświetlony zostanie tekst za pomocą dużej czcionki Arial.
Listing 17.6. LST18_6.CPP - tworzenie czcionek za pomocą funkcji CreatePointFont ()
1 void CSimpTextView::OnDraw(CDC* pDC)
2 {
3 CSimpTextDoc* pDoc = GetDocument();
4 ASSERT_VALID(pDoc);
5
6 // TODO: tu dodaj kod rysowania dla własnych danych 1
8 // ** Utworzenie czcionki Arial o rozmiarze 36 punktów
9 CFont fnBig;
10 fnBig.CreatePointFont(360,"Arial",pDC); O
11
12 CFont* pOldFont = pDC->SelectObject(SfnBig);
13
14 pDC->TextOut(50,50,"** 36 Pt Arial Font **");
15
16 pDC->SelectObject(p01dFont);
17 )


Korzystanie z czcionek 431
O Funkcja CreatePointFontt) daje możliwość szybkiego i łatwego tworzenia czcionek o określonym
kroju i rozmiarze.
Zauważmy, iż w linii 10 przekazano funkcji wartość 360. Wielkość czcionki została
bowiem podana w dziesiątych częściach punktu. Daje to większą elastyczność w ustalaniu
rozmiaru czcionki. Po uruchomieniu skompilowanego programu ujrzymy na ekranie tekst
(ustalony w linii 14), wyświetlony za pomocą czcionki Arial o rozmiarze 36 punktów.
Tworzenie czcionek za pomocą funkcji CreateFont()
Funkcja CreateFont () jest prawdopodobniej jedną z najsprytniejszych funkcji, jakie możemy
znaleźć w MFC. Jest również jedną z najobszerniejszych, gdyż wymaga 14 parametrów, którymi są w
większości złożone kombinacje znaczników. Prototyp funkcji widoczny jest na listingu 17.7.
Listing 17.7. LST18_7.CPP - parametry dla funkcji CreateFont ()
1 BOOL CreateFont( int nHeight, int nWidth,
2 int nEscapement, int nOrientation, int nWeight,
3 BYTE bitalic, BYTE bUnderline, BYTE cStrikeOut,
4 BYTE nCharSet, BYTE nOutPrecision,
5 BYTE nClipPrecision, BYTE nQuality,
6 BYTE nPitchAndFamiły, LPCTSTR IpszFacename ) ;
Ustalanie wysokości i szerokości czcionki
Dwa pierwsze parametry funkcji CreateFont () służą do ustalenia wysokości i szerokości żądanej
czcionki. Pierwszy parametr, nHeight, może być ujemny lub dodatni. Jeśli ustalimy wartość dodatnią,
program zarządzający będzie poszukiwał czcionki zbliżonej wysokością do oczekiwanej, odnosząc się
do wymiaru komórki czcionki. Podanie wartości ujemnej powoduje poszukiwanie czcionki w oparciu o
wysokość znaku.
Różnica pomiędzy komórką czcionki i znakiem jest taka, iż komórka posiada pewne puste obszary
pod i ponad znakiem, natomiast wysokość znaku to wysokość komórki po odjęciu tych pustych
obszarów. Wartość zero komunikuje programowi zarządzającemu, iż powinien poszukiwać czcionki
według założeń domyślnych.
Parametr nWidth określa średnią szerokość żądanej czcionki (czcionki proporcjonalne posiadają
znaki szersze i węższe). Przekazując wartość zero powodujemy, iż program zarządzający będzie
poszukiwał czcionek według domyślnych zasad, bazując na wysokości oraz proporcjach czcionki.


432 ____________ Poznaj Visual C++ 6
Zasady dopasowywania wysokości czcionki
Podczas dopasowywania czcionki poszukiwana jest czcionka najwyższa, jednak niższa niż określona
wysokość.
Ustalanie pochylenia i orientacji czcionki
Za pomocą parametrów Escapement i Orientation możemy ustalać pochylenie i orientację tekstu, a
także obracać znaki.
Parametr nEscapement pozwala rysować kolejne znaki pochylone pod podanym w dziesiątych
częściach stopnia kątem względem osi x. Wartość 900 daje tekst pionowy.
Parametr nOrientation określa kąt, pod jakim przebiega podstawa znaku, względem osi x, podawana
również w dziesiątych stopnia.
Ustalanie pogrubienia, kursywy, podkreślenia i przekreślenia
Kolejne cztery parametry odnoszą się do grubości czcionki (która może być pogrubiana) i
umożliwia wybór dodatkowych stylów, takich jak kursywy, podkreślenia oraz przekreślenia.
Parametr nWeight pozwala określić grubość czcionki, od O (bardzo cienka) do 1000 (bardzo gruba).
Predefiniowane wartości podane są w tabeli 17.2.
Tabela 17.2. Znaczniki wagi czcionki
Znacznik Wartość wagi
FW_DONTCARE Q
FWJTHIN 100
FW_EXTRALIGHT 200
FW_LIGHT 300
FW_NORMAL 4QO
FW_MEDIUM 500
FWJSEMIBOLD 600
FW_BOLD 700
FW_EXTRABOLD g00
FW_HEAVY 900


Korzystanie z czcionek___________________________ __ 433
Parametr bitalic powoduje zastosowanie kursywy, jeśli ustaloną jego wartością jest
TRUE.
Parametr bUnderline powoduje użycie czcionki z podkreśleniem, jeśli jego wartością
jest TRUE.
Parametr bStrikeOut natomiast powoduje użycie czcionki przekreślonej, jeśli jego wartość
równa jest TRUE.
Równoważne znaczniki wagi czcionki
Oprócz wymienionych, spotkać można również inne znaczniki, takie jak
FWJJLTRALIGHT, FW_REGULAR, FW_DEMIBOLD, FWJJLTRABOLD, FW_BLACK, które
równoważne są ze znacznikami odpowiednio FW_EXTRALIGHT, FWJMORMAL, FW_SEMI-
BOLD,FW EXTRABOLD oraz FW HEAVY.
Ustalenia dotyczące jakości i precyzji
Parametry jakości i precyzji pozwalają ustalić, w jaki sposób czcionki będą wybierane i
modelowane na urządzeniu docelowym. Istnieją poza tym możliwości dodatkowych ustaleń,
takich jak stałe lub proporcjonalne odległości między znakami, a także użycie szeryfów.
Parametr nCharSet pozwala wybrać zestaw znaków. Zwykle będzie to ANSI_CHAR-SET,
ustalający zestaw ANS l. Czasami jednak niezbędne jest wybranie SYMBOL_CHAR-SET, co
pozwala korzystać z zestawu symboli zamiast zwykłych liter.
Parametr nOutPrecision określa, w jaki sposób program zarządzający czcionkami będzie
wybierał jedną czcionkę w zastępstwie innej. Zwykle stosowanym jest
OUT_DEFAULT_PRECIS, lecz jeśli koniecznie chcemy korzystać z czcionek TrueType,
możemy wybrać OUT_TT_PRECIS.
Parametr ndipprecision ustala precyzję obcinania. Zwykle wybranym trybem jest
CLIP_DEFAULT_PRECIS.
Parametr nQuality pozwala określić kompromis pomiędzy jakością wyświetlanych znaków a
dopasowaniem ich do innych, ustalonych parametrów. Używanymi trybami
Są DEFAULT_QUALITY, DRAFT_QUALITY Oraz PROOF_QUALITY.
Parametr nPitchAndFamiły umożliwia ustalenie dwóch rzeczy jednocześnie. Może to być
powodem komunikatu o błędzie kompilatora, który powie o niemożności przyjmowania
przez CreateFont 15 parametrów. Jeśli otrzymamy taki komunikat, powinniśmy
sprawdzić, czy podane wartości są połączone ze sobą (operatorem + lub II), a nie
oddzielone przecinkiem.


434__________________________________ Poznaj Visual C++ 6
Alternatywne znaczniki precyzji obcinania
Znaczniki te zmieniają sposób obcinania czcionki, gdy tekst nie mieści się w obszarze rysowania.
Znacznik CLIP_EMBEDDED może być użyty w stosunku do osadzonych czcionek tylko do odczytu.
Znacznik CLIP_ANGLES natomiast zastosować można, gdy zmieniona została orientacja tekstu. W
starszych kodach można spotkać inne znaczniki, lecz większość z nich nie znajduje się już w użyciu i
może być zignorowana.
Wartości możliwe do ustalenia dla odstępów międzyznakowych podane są w tabeli 17.3. Tabela
17.3. Ustawienia odstępów


Znacznik
DEFAULT_PITCH
VARIABLE_PITCH
FIXED PITCH
Opis
Typowy dla danej czcionki
Odstępy zmienne
Odstępy stałe, użyteczne dla emulatorów terminali





Znaczniki wymienione w tabeli 17.3 możemy łączyć ze znacznikami rodzin typograficznych,
wymienionymi w tabeli 17.4. Dla przykładu, można połączyć ze sobą znaczniki DEFAULT_PITCH | |
FF_SCRIPT w celu uzyskania czcionki o domyślnych odstępach i stylu pisma ręcznego.
Stosowanie czcionek Tnie Type
Używając znacznika TMPF_TRUETYPE w połączeniu ze znacznikiem rodziny czcionki można wybierać
czcionki True Type danej rodziny.
Tabela 17.4. Znaczniki rodziny typograficznej
Znacznik rodziny Opis
FF_DECORATIVE Czcionki oryginalne
FF_DONTCARE Bez znaczenia
FF_MODERN Stałe odstępy lub szerokość kreski
FF_ROMAN Proporcjonalne odstępy, zmienna grubość kreski
FF_SCRI PT Styl pisma ręcznego
FF_SWISS Odstępy proporcjonalne, lecz bez szeryfów
TMPFJTRUETYPE Wymagana wersja TrueType


Korzystanie z czcionek____________________________________435
Czcionki TrueType rysowane są za pomocą serii krzywych. Z tego też względu po powiększeniu
wyglądają znacznie lepiej niż czcionki rastrowe.
Określanie nazwy czcionki
Parametr IpszFacename umożliwia określenie nazwy jednej spośród zainstalowanych w systemie
czcionek, na przykład Times New Roman.
Tworzenie czcionki za pomocą funkcji CreateFont()
Spróbujmy zatem utworzyć czcionkę, którą następnie użyjemy w kolejnym przykładzie.
Wprowadzimy zmiany w treści funkcji składowej widoku OnDraw (), widoczne na listingu 17.8. Listing
wyświetli kilka linii tekstu, obróconych wokół punktu środkowego poprzez zmianę orientacji kolejnych
linii w zakresie kąta pełnego, czyli 360 stopni.
Listing 17.8. LST18_8.CPP - tworzenie czcionek za pomocą funkcji CreateFont ()





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void CSimpTextView::OnDraw(CDC* pDC) { .
CSimpTextDoc* pDoc = GetDocument() ;
ASSERT_VALID(pDoc) ;
// TODO: tu dodaj kod rysowania dla własnych danych
II ** Deklaracja obiektu CRect dla obszaru roboczego CRect
rcCIient;
GetCIientRect(SrcCIient) ;
// ** Ustalenie punktu środkowego CPoint ptCentre
= rcCIient.CenterPointO;
pDC->SetBkMode(TRANSPARENT) ;
// ** Pęt-la przez 360 stopni
for(int i=0 ; i <360 ; i+=18) (
CFont fnBig;
// ** Wysokość czcionki 30 punktów, szerokość domyślna
fnBig.CreateFont(30,0, O
// ** Zmiana orientacji
i*10,i*10,
// ** Zwiększenie wagi czcionki i/4,
FALSE, TRUE, //** Podkreślenie


436_____________________________________Poznaj Visual C++ 6
29 FALSE,
30 ANSI_CHARSET,
31 OUT_DEFAULT_PRECIS,
32 CLIP_DEFAULT_PRECIS,
33 PROOF_QUALITY,
34 DEFAULT_PITCH + FF_DONTCARE,
35 "Arial"
36 );
37
38 CFont* pOldFont = pDC->SelectObject(SfnBig);
39
40 // ** Rysowanie tekstu
41 pDC->TextOut(ptCentre.x,ptCentre.y, @
42 ".....Beautiful Fonts") ;
43
44 pDC->SelectObject(pOldFont) ;
45 )
46 }
O CreateFont () zezwala na pasowanie i utworzenie kroju, lecz może on nie spełniać
warunków określonych parametrami.
Funkcja Text0ut () wyświetla kolejne, obrócone linie tekstu.
Na powyższym listingu w liniach 17-44 następuje obracanie kolejnych linii tekstu wokół
punktu środkowego, określonego w linii 13. Potężna funkcja CreateFont () rozpoczyna
działanie w linii 22. W linii 26 przekazany jej jest znacznik nakazujący zwiększanie wagi
czcionki. Kąt obrotu kolejnych linii tekstu przekazany jest poprzez parametry Escapement
oraz Orientation w linii 24, nakazując przechylanie czcionki o stałą wartość kątową, w
kolejnych powtórzeniach pętli.
Gdy skompilujemy i uruchomimy program, ujrzymy kilkanaście linii tekstu, owiniętych
wokół punktu środkowego, jak na rysunku 17.2.


Korzystanie z czcionek 437
518 Erfil
5M"J.

Rysunek 17.2. Obracanie tekstu za pomocą funkcji CreateFont ()
Jednokrotne tworzenie czcionek
Utworzenie czcionek potrzebnych danej aplikacji i zapisanie ich w formie składowych zmiennych
pozwala na przyspieszenie działania aplikacji, gdyż czcionki nie muszą być tworzone do
każdorazowego użycia.
Wybór czcionek
Użytkownik Windows może wybierać czcionki spośród szerokiego zakresu krojów. Wiele aplikacji,
nie tylko do edycji tekstu, oferuje taką możliwość jako standardową opcję. By nadać tę cechę własnej
aplikacji, musimy uzyskać dostęp do listy zainstalowanych czcionek. GDI umożliwia to poprzez funkcje
wyliczające czcionki oraz specjalne okna dialogowe.
Wyliczanie czcionek
W jaki sposób program może pobrać listę czcionek wraz z ich ustawieniami? Odpowiedzią na to
pytanie jest funkcja EnumFont Familie s () oraz stowarzyszona z nią funkcja zwrotna (ang.
calibackfunction).
Funkcja zwrotna ustanawia funkcję wywoływaną dla każdej pozycji listy, przekazującą jej nazwę
czcionki. Funkcja wyliczająca przegląda całą listę (w tym przypadku czcionek) i wywołuje funkcję
zwrotną dla każdej odnalezionej pozycji.


438 Poznaj Visual C++ 6
Możemy nakazać funkcji wyliczającej (ang. enumerator) przejście przez całą listę czcionek i
pobranie wszelkich dostępnych informacji. Funkcja wyliczająca przekazuje następnie owe informacje
funkcji zwrotnej.
Możemy wyświetlić listę zainstalowanych czcionek z ich domyślnymi ustawieniami, co widoczne
jest na rysunku 17.3. Kod listingu 17.9 i związane z nim objaśnienia, pokazują, w jaki sposób można
wykorzystać funkcję EnumFontFamilies () do tego zadania.
W celu wyświetlenia listy czcionek (takiej jak na rysunku 17.3) musimy przed kodem funkcji
onDraw () umieścić kod funkcji zwrotnej. Zauważmy, iż jest to funkcja globalna, dlatego też nie
widzimy nazwy żadnej klasy przed jej nazwą własną. Musimy ją umieścić powyżej OnDraw (), gdyż w
przeciwnym wypadku, musielibyśmy dodać deklarację funkcji przed OnDraw (). Wywołanie
EnumFontFamilies () możemy natomiast umieścić wewnątrz OnDraw (), co widać na listingu 17.9.
"..,,_.."....." , ,"" ......,,,. .,._,......".._.....".........,,
System
Fixtdsys
Teminal
MS Serit
MS Sons Serrt
Courier
&W3*
Roman
lOC/lipt
Modern
D^xrr^^
Arial
Courier New
E\^jJ,po^
Times New Roman
tXBV)o^X^
iSt/WK:. i:i:fli1 ,:il!lilF SSSSSSsf^
Rysunek 17.3. Czcionki wyhstowane przez EnumFontFamilies ()
Listing 17.9. LST18_9.CPP - wyliczenie i wyświetlenie zainstalowanych czcionek
// ** Funkcja zwrotna int CALLBACK FontCallBack(ENUMLOGFONT
FAR* Ipelf, O
NEWTEXTMETRIC FAR *lpnt,
int FontType,
LPARAM IParam) (
// ** Pobranie z IParam wskaźnika kontekstu urządzenia


Korzystanie z czcionek 439
CDC* pDC = (CDC*)lParam;
CFont fnEnum;
// ** Pośrednie utworzenie czcionki
fnEnum.CreateFontIndirect(&lpelf->elfLogFont);
CFont* pOldFont = pDC->SelectObject (SfnEnuin) ;
// ** Ustalenie bieżącej pozycji kursora int
nYPos = pDC->GetCurrentPosition().y;
// ** Wyświetlenie nazwy czcionki pDC-
>TextOut(5,nYPos,CString(lpelf->elfLogFont.
IfFaceName)) ;
//** Move down by the height of the font pDC->MoveTo(0,nYPos
+ lpelf->elfLogFont.IfHeight);
pDC->SelectObject(p01dFont) ;
// ** Zwrócenie TRUE dla kontynuacji
return TRUE;
l l l l l l l l l l l l l l l l l l l l l l / l l l l l l l l l l l l l l l l l l l l l l l l l l l t l l l II CSimpTextView
drawing
void CSimpTextView::OnDraw(CDC* pDC) (
CSimpTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc) ;
// TODO: tu dodaj kod rysowania dla własnych danych
II ** Ustawienie funkcji wyliczającej EnumFontFamilies(pDC-
>Get3afeHdc(),NULL, O
(FONTENUMPROC)FontCallBack,(LPARAM)pDC) ;
}
O Funkcja zwrotna będzie wywoływana dla każdej czcionki zainstalowanej w systemie. Informacje o
czcionce przekazywane będą jako parametry.


440_____________________________________Poznaj Visual C++ 6
@ Funkcja CreateFontindirect () jest tożsama z CreateFont(), lecz parametry przekazywane są jej jako
składowe struktury LOGFONT.
Funkcja MoveTo () jest wywoływana w celu ustawienia kursora w gotowości do wyświetlenia
kolejnej czcionki.
O Adres funkcji zwrotnej przekazywany jest do EnumFontFamilies (), a zatem może ona wywoływać
tę funkcję dla każdej czcionki.
Na listingu 17.9 pierwszą funkcją, której treść mieści się w liniach 1-29, jest funkcja zwrotna. Jest
ona wywoływana dla każdej odnalezionej w systemie czcionki, a jej parametrami są informacje o danej
czcionce. Co się więc tutaj dzieje? W funkcji onDraw() ustanowiona została funkcja wyliczająca.
Parametr l param jest wartością definiowaną przez użytkownika, która została ustanowiona w linii
44 jako wskaźnik kontekstu urządzenia. Kontekst ten użyty jest do narysowania wszystkich
kompatybilnych z nim czcionek (w tym przypadku urządzeniem jest monitor).
Funkcja CreateFontindirect () wywołana w linii 12 działa w taki sam sposób jak CreateFont (), lecz
pobiera strukturę przechowującą wszelkie parametry, co widać z listingu 17.11.
Drugim parametrem funkcji wyliczającej w linii 44 jest rodzina czcionki. Przekazując wartość NULL
spowodujemy wyświetlenie wszystkich możliwych czcionek. Jeśli natomiast wskażemy określoną
rodzinę, na przykład Arial lub Courier, na ekranie ujrzymy tylko czcionki należące do tej rodziny.
Trzecim parametrem jest nazwa funkcji zwrotnej, którą możemy ukryć w (FONTENUM-PROC),
zapobiegając ostrzeżeniom kompilatora.
Na koniec możemy przekazać pewne informacje użytkownika. Ponieważ czcionki mają być
rysowane, wskazanie kontekstu urządzenia (w którym będzie się to odbywało) jest prawdopodobnie
najużyteczniejszą spośród informacji.
Jak widzimy, funkcja wyliczająca odnajduje listę zainstalowanych czcionek, rozpoczyna
wywoływanie funkcji zwrotnej FontCallBack () i przekazuje jej kilka parametrów. Pierwszym jest
struktura ENUMLOGFONT. Listing 17.10 przedstawia jej definicję.
Listing 17.10. LST18_10.CPP- struktura ENUMLOGFONT
1 typedef struct tagENUMLOGFONT {
2 LOGFONT elfLogFont;
3 BCHAR elfFullName[LF_FULLFACESIZE];
4 BCHAR elfStyle[LF_FACESIZE] ;
5 } ENUMLOGFONT;


Korzystanie z czcionek 441
ENUMLOGFONT przechowuje nazwę elfFullName oraz styl elfstyle czcionki lecz prawdopodobnie
najużyteczniejszą częścią jest przechowywana tu struktura LOGFONT. Jest to struktura wszystkich
parametrów, jakie można przekazać funkcji CreateFont (). Jak widzieliśmy w linii 12 listingu 17.9, może
być użyta również przez CreateFontindirect ().
Typ danych BCHAR
Typ danych BCHAR można napotkać w strukturach Win32. Typ ten jest definiowany jako BYTE podczas
kompilacji w środowisku nie będącym środowiskiem Unicode lub jako WCHAR w środowisku Unicode.
Unicode reprezentuje każdy znak w formie dwubajtowej sekwencji, pozwalając na utworzenie do 65
536 znaków, co umożliwia tworzenie zestawów znaków narodowych, a także symboli.
Listing 17.11 przedstawia sposób definiowania tej struktury. Listing
17.11. LST18_11.CPP-struktura LOGFONT
1 typedef struct tagLOGFONT ( // If
2 LONG IfHeight;
3 LONG IfWidth;
4 LONG IfEscapement;
5 LONG IfOrientation;
6 LONG IfWeight;
7 BYTE Ifitalic;
8 BYTE IfUnderline;
9 BYTE IfStrikeOut;
10 BYTE IfCharSet;
11 BYTE IfOutPrecision;
12 BYTE IfCIipPrecision;
13 BYTE IfOuality;
14 BYTE IfPitchAndFamiły;
15 TCHAR !fFaceName[LF_FACESIZE] ;
16 } LOGFONT;
Dostęp do szczegółów struktury uzyskujemy poprzez wskaźnik struktury ENUMLOGFONT ipelf
przekazany funkcji zwrotnej (co następuje w linii 2 listingu 17.9). Jest on użyty po raz pierwszy w liniil2
(poprzez kod &lpelf->elfLogFont, służący do określenia adresu struktury LOGFONT).
Kolejnym parametrem przekazanym funkcji zwrotnej w listingu 17.9 jest struktura
NEWTEXTMETRIC. Struktura ta służy do przechowania szczegółów dotyczących rozmiarów znaków i
sposobu prezentacji w określonym kontekście urządzenia.


442 Poznaj Visual C++ 6
Dalej przekazywany jest parametr FontType informujący nas, czy dana czcionka jest
typu TRUETYPE_FONTTYPE, RASTER_FONTTYPE bądź DEVICE_FONTTYPE. Na końcu znaj-
duje się wskaźnik kontekstu urządzenia pod postacią LPARAM.
Po utworzeniu i wybraniu czcionki odnajdujemy bieżącą pozycję kursor graficznego w
kontekście urządzenia, stosując funkcję GetCurrentPosition (), co widać w linii 17 listingu
17.9. Nazwę czcionki możemy pobrać ze struktury LOGFONT (linia 20 listingu 17.9) i
wyświetlić ją poprzez wywołanie funkcji Text0ut ().
Pozycja kursora może być zmieniona o wysokość czcionki i ustalona za pomocą funkcji
MoveTo (), jak w linii 23. Po usunięciu wyboru starej czcionki należy zwrócić TRUE do funkcji
wyliczającej, co pozwoli jej kontynuować działanie. Przekazanie FALSE zinterpretowane
zostanie jako zakończenie działania.
Struktury TEXTMETRICS
Struktury NEWTEXTMETRICS są potomnymi struktur TEXTMETRICS. Istnieje wiele odmiennych struktur
Win32 i wiele spośród funkcji może wymagać tych odmiennych wersji. Napotkać można również
struktury NEWTEXTMETRICSEX, TEXTMETRICW oraz TEXTMETRICA, które zależą od sygnatur czcionek
środowiska Unicode i środowisk odmiennych.
Używanie okna dialogowego wyboru czcionki
Windows dostarcza standardowego okna dialogowego pozwalającego na dokonanie wy-
boru czcionki. Większość aplikacji używa tych okien i każdy korzystał z nich wielokrotnie.
Możemy umieścić takie okno we własnej aplikacji, dodając pozycję menu umożliwiającą
jego otwarcie. Musimy więc utworzyć pozycję menu z nagłówkiem Choose Font (jak na
rysunku 17.4.) i identyfikatorem ID_CHOOSEFONT. Algorytm "Dodawanie nowej pozycji
menu" opisany w rozdziale 13 opisuje sposób wykonania tego zadania.
Następnie należy utworzyć funkcję obsługi komunikatu MESSAGE o nazwie OnChoose-
Font () dla nowej pozycji menu (ID_CHOOSEFONT) wykonując algorytm "Dodanie za pomocą
CIassWizard funkcji obsługi poleceń menu", znajdujący się również w rozdziale 13.
Menu Item PropBrties


Generał Extended Styles
10: IlIJMihMddiMgiii3 caption:
S~ Separator t~ Pop-up T lnactive Break:


F Checked r Grayed F Hełp Proropt





Rysunek 17.4. Dodawanie do menu pozycji wyboru czcionki


Korzystanie z czcionek 443
Add Member Function
Rysunek 17.5. Tworzenie funkcji obsługi OnChooseFont
Skoro mamy nową pozycję menu i obsługującą ją funkcję, możemy dodać i użyć klasę CFontDialog,
co pokazane jest na listingu 17.12.
Listing 17.12. LST18_12.CPP - implementacja funkcji obsługi OnChooseFont ()





1
2
3
4
5
6
7
8
9
10
11
12
13
14
void CSimpTextView::OnChoosefont() (
// TODO: Add your command handler code here
// ** Deklaracja CFontDialog CFontDialog
dIgChooseFont; O if
(dIgChooseFont.DoModal() == IDOK) {
m fnCustom.DeleteObject();
m fnCustom.CreateFontIndirect(
dIgChooseFont.m_cf.IpLogFont) ;
Invalidate() ;





O CFontDialog jest klasą osłonową dla standardowego okna dialogowego CHOOSE-FONT i dostarcza
prostej lecz wyrafinowanej metody wybierania określonej czcionki i jej stylu.
Na powyższym listingu, w linii 6 zadeklarowany zostaje obiekt CFontDialog jako dIgChooseFont.
Możemy więc otworzyć okno dialogowe poprzez wywołanie w linii 7 funkcji DoModal (). Użytkownik
może dokonać wyboru czcionki. Po kliknięciu OK, musi zostać wywołana funkcja DeleteObject () dla
obecnej czcionki w celu uwolnienia obiektu GDI. Następnie tworzona jest przez składową CFontDialog,
m_cf która posiada wskaźnik do struktury LOGFONT. Dalej następuje wywołanie Invalidate () (linia 12),
co wymusza odświeżenie widoku.
Musimy również dodać do klasy widoku zmienną czcionki, m_fnCustom. Klikniemy więc kartę
ClassView w widoku Project Workspace, a następnie podwójnym kliknięciem


444___________________________________Poznaj Visual C++ 6
otworzymy kod deklaracji klasy CSimpTextView. Dodamy nową zmienną, umieszczając ją za
komentarzem // Attributes, co widać na listingu 17.13.
Listing 17.13. LST18_13.CPP - dodanie składowej zmiennej do klasy widoku
1 // Atrybuty
2 public:
3 // ** Nowa dodana zmienna czcionki
4 CFont m fnCustom;
5
6 CSimpTextDoc* GetDocument();
Na koniec powinniśmy zmienić implementację OnDraw (), by wyświetlała tekst przy użyciu
wybranej czcionki. Listing 17.14 prezentuje właściwy kod.
Listing 17.14. LST18_14.CPP - wyświetlanie wybranej czcionki
1 void CSimpTextView::OnDraw(CDC* pDC)
2 {
3 CSimpTextDoc* pDoc = GetDocument();
4 ASSERT_VALID(pDoc) ;
5
6 // TODO: tu dodaj kod rysowania dla własnych danych
7
8 CFont* pdldFont = pDC->SelectObject(&m_fnCustom);
9 pDC->TextOut(20,20,
10 "Bań bah black sheep, have you any wool") ;
11 pDC->SelectObject(pOldFont);
12 }
Czcionka wybrana zostaje w linii 8 listingu 17.14, a funkcja Text0ut() wyświetla próbny tekst w
liniach 9 i 10.
Teraz skompilujemy i uruchomimy program. Jeśli wszystko przebiegnie pomyślnie, będziemy mieli
możliwość zmiany czcionki, którą wyświetlany jest tekst na ekranie. Dostęp do okna wyboru uzyskać
możemy wybierając pozycję Choose Font z menu Edit. Zmienimy teraz ustawienia w tym oknie, a tekst
zostanie wyświetlony ponownie inną czcionką, jak na rysunku 17.6.


Korzystanie z czcionek 445
w. ':''' "'^^^ysip ^"^
Eii'e"&tt yTw atip'"
D|e!|a| ^l^M a|'j?[
Bah bah black sheep. have you any wool





RS-
'TArielBlai 'l- Aliol
Noirow t
BookAntique "*t
Bookrnan Old
Style ''f Bool-yhell
Symboli
OK
Cance!



EtiBCiE

r S&ikaout
y iyndertin^
i^olor:
AaBbYyZ




Rysunek 17.6. Okno wyboru czcionki
PATRZ TAKŻE
O dodawaniu i implementowaniu menu oraz ich stylach czytaj w rozdziale 13.
Rysowanie tekstu formatowanego i wieloliniowego
Ponieważ odmienne wymiary czcionek powodują zmiany w wykorzystywanym obszarze
widoku, ważnym zadaniem jest utworzenie kodu powodującego prawidłowe sformatowanie
tekstu względem określonego okna. Na szczęście Windows posiada funkcję, która wspomaga
nas w tym zadaniu. DrawText () pobiera trzy parametry. Pierwszym jest obiekt cstring, w
którym znajduje się łańcuch znakowy przeznaczony do wyświetlenia. Drugi parametr stanowi
wskaźnik prostokąta, w którym tekst ma zostać umieszczony. Ostatni parametr (co nie znaczy
najmniej ważny) jest znacznikiem, którego wartość determinuje sposób wyświetlenia i
formatowania tekstu.
Znaczniki możemy łączyć na różne sposoby, ustalając w ten sposób odmienne opcje.
Znaczniki są przedstawione w tabeli 17.5.
Stosowanie funkcji DrawTextEx ()
Istnieje rozszerzona wersja funkcji DrawText (), zwana DrawTextEx (). Jest ona dostępna jedynie jako
globalna funkcja Win32, należy zatem przekazać jej jako pierwszy parametr, uchwyt urządzenia
docelowego. Forma rozszerzona posługuje się tymi samymi parametrami, zezwalając jednakże na
przekazanie wskaźnika struktury DRAWTEXT PARAMS w postaci ostatniego parametru. Struktura ta może
być wykorzystana do ustalania pozycji tabulacji, jak również marginesów.


446_____________________________________Poznaj Visual C++ 6
Tabela 17.5. Znaczniki formatowania przekazywane funkcji DrawText ()
Wartość znacznika Opis
DT_LEFT Wyrównanie tekstu do lewej strony okna
DT_RIGHT Wyrównanie tekstu do prawej strony okna
DT_CENTER Wysrodkowanie tekstu w oknie
DT_VCENTER Wysrodkowanie tekstu w pionie
DT_WORDBREAK Nie dzieli wyrazów (jak edytor tekstu)
DT_CALCRECT Nie rysuje tekstu. Oblicza obramowanie okna
DT_EXPANDTABS Poszerza tabulację (domyślna wartość 8)
DT_NOPREFIX Wytacza stosowanie prefiksów. W przeciwnym wypadku znak &
oznacza skrót klawiaturowy
DT_TOP Wyświetla tekst u góry okna (tylko w przypadku pojedynczej linii)
DT_BOTTOM Wyświetla tekst u dołu okna (tylko w przypadku pojedynczej linii)
Możemy teraz zmodyfikować funkcję OnDraw (), by korzystała z DrawText () zamiast Text0ut
(). Wzór stanowi listing 17.15.
Listing 17.15. LST18_15.CPP- rysowanie tekstu formatowanego przez DrawText ()





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void CSimpTextView::OnDraw(CDC* pDC) {
CSimpTextDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc) ;
// TODO: tu dodaj kod rysowania dla własnych danych
CFont* pOldFont = pDC->SelectObject(&m_fnCustom) ;
CRect rcSmall(CPoint(20,20),CPoint(200,100)) ;
pDC->Rectangle(rcSmall) ;
pDC->SetBkMode(TRANSPARENT) ;
// ** Wywołanie DrawText w celu odrysowania tekstu II **
Przenoszenie wyrazów i Wysrodkowanie tekstu
pDC->DrawText(
"Bah bah black sheep, have you any wool",
rcSmall, DT WORDBREAK + DT CENTER);


Korzystanie z czcionek 447
20 pDC->SelectObject(p01dFont); O
21 }
O Przekazując znaczniki DT_WORDBREAK i DT_CENTER funkcji DrawText () powodujemy przenoszenie
wyrazów w całości oraz wyśrodkowanie tekstu w określonym prostokącie.
W liniil6 listingu 17.15 widzimy wywołanie funkcji DrawText (), użytej do narysowania
przykładowego tekstu w prostokącie rcSmall. Jeśli teraz skompilujemy i uruchomimy program,
zobaczymy tekst pośrodku prostokąta, w którym przenoszone do nowej linii są całe wyrazy, co widać na
rysunku 17.7. Zmieniając wielkość czcionki możemy obserwować wpływ tej czynności na format tekstu
wewnątrz prostokąta.
PATRZ TAKŻE
O wprowadzaniu tekstu do pól edycji czytaj w rozdziale 5.
Usuwanie czcionek
Podobnie jak w przypadku innych klas osłonowych, czcionki GDI są automatycznie usuwane, gdy
obiekty osłonowe wychodzą z użycia. Możemy je usuwać własnoręcznie, wywołując funkcję
DeleteObject () (tylko wtedy, gdy dana czcionka nie jest aktualnie umieszczona w kontekście
urządzenia). Po jej wykonaniu ponownie możemy użyć klasy osłonowej wywołując jedną z jej funkcji
Create.
&le Edit yiew tfelp
Q|a|H| :

'r;) g"!
a|?

J















Boh bah black
sheep, have you




any wool

^B^ft^s-^BiiiHIlgII^ a" se;



:^|Centuiy Gothic ,|i.| =teguler JH j OK ]



;>,: IT Bookshelf Symbol 2 ^: :^ ^Bookshelf
Symbol 3 ..^ 1^ ^ BookshBlI Symbol 4 i^
:^ TtBook-shBlf Symbol 5 l;

Ita
lie
Bold
Bold
Italie

1
0
1
]
1
-
1

-'- Canctl |
J







w.

WEmss^^m i





1
6





: l 'T Cenimy Schoolbook





1
3











'T Cumie SansMS
^j



J

2
0

JJ



Ettecte Sample







r SU^eo'Jt . r iJnrisilina

AoBbYyZz







Qoloi :













^Eilack ^j Sci-ipt:







:.. ........ ....
.."..,...",^...,.^,

W

eslern

4::". "-,







..;-^iiil^^iyi^

|:||:











ll^.,.......
^^^N^liS

^i^iiS^^^ii^l^^
^^^












Rysunek 17.7. Tekst sformatowany przez funkcję DrawText ()


448_____________________________________Poznaj Visual C++ 6
Spośród wszystkich obiektów GDI czcionki są najprawdopodobniej najbardziej "pamięciożerne",
dlatego wskazane jest, o ile to możliwe, usuwanie wszystkich nieużywanych czcionek. Jeśli zamierzamy
użyć ich ponownie, najlepszym rozwiązaniem będzie utworzenie zmiennych składowych klasy widoku,
które będziemy mogli wybierać i usuwać, zamiast tworzyć je za każdym razem, gdy dokonujemy
rysowania, co spowalnia działanie programu.
PATRZ TAKŻE
Więcej szczegółów dotyczących obiektów GDI znajdziesz w rozdziale 15.


Wyszukiwarka

Podobne podstrony:
Cin 10HC [ST&D] PM931 17 3
17 Prawne i etyczne aspekty psychiatrii, orzecznictwo lekarskie w zaburzeniach i chorobach psychiczn
17 (30)
Fanuc 6M [SM] PM956 17 3
ZESZYT1 (17)
17 Iskra Joanna Analiza wartości hemoglobiny glikowanej Hb
1 02 Korzystanie z zalet zintegrowanego ¶rodowiska programi
B 17 Flying Fortress II The Mighty 8th Poradnik Gry Online
Obj 7w 17 BÓG OTRZE WSZELKĄ ŁZĘ

więcej podobnych podstron