Wywoływanie standardowego okna Czcionka

Stronę tą wyświetlono już: 251 razy

Wstęp

Kolejnym często spotykanym w wielu programach standardowym oknem systemu Windows jest okno wyboru czcionki, które w polskiej wersji językowej ma nazwę Czcionka. Do wywołania tego okna służy funkcja ChooseFont, która przyjmuje jako jedyny parametr wskaźnik do struktury typu CHOOSEFONT. Aby skorzystać z tej funkcji konieczne jest załączenie do projektu biblioteki:

Listing 1
  1. #include <commdlg.h>

Wykorzystam funkcję w projekcie myNotepad by w praktyczny sposób pokazać, jak można w prosty sposób zwiększyć funkcjonalność tego programu.

Okno dialogowe Czcionki
Rys. 1
Okno dialogowe Czcionki

Dodawanie modyfikacja menu programu myNotepad

Zanim zacznę modyfikację samego kodu programu warto dodać do menu głównego dodatkowe menu Ustawienia i w tej pozycji dodatkową pozycję Czcionka, identyfikator tej pozycji powinien być z automatu ustawiony na ID_USTAWIENIA_CZCIONKA, jeżeli tak nie jest to proszę to zmienić. Do zasobów można się dostać wciskając kombinację Ctrl+Shift+E lub wybierając z menu View->Resource View i pojawi się okno o nazwie Resource View, w którym na rozwijanej liście można znaleźć menu z projektu. Kliknięcie tej pozycji otworzy edytor graficzny tegoż menu, które po wprowadzeniu modyfikacji powinno wyglądać jak na poniższym rysunku.

Zmodyfikowane menu projektu myNotepad
Rys. 2
Zmodyfikowane menu projektu myNotepad

Wprowadzenie poprawek do kodu programu myNotepad

Menu zostało zmodyfikowane, trzeba teraz na samym początku projektu załączyć wcześniej wspomniany plik commdlg.h. Teraz zaraz za bibliotekami załączonymi do projektu wstawić trzeba następującą funkcję odpowiedzialną za pozyskiwanie uchwytu czcionki:

Listing 2
  1. #include <windows.h>
  2. #include <commdlg.h>
  3. #include <locale.h>
  4. #include "resource.h"
  5. #define ID_EDIT 3 // identyfikator kontrolki edit do przechowywania tekstu
  6. HFONT GetChooseFont(HWND hWnd, LOGFONT *lf, COLORREF *c){
  7. CHOOSEFONT cf;
  8. ZeroMemory(&cf, sizeof(cf)); // zerowanie pól struktury
  9. cf.lStructSize = sizeof(cf); // ustawienie pola określającego rozmiar struktury
  10. cf.hwndOwner = hWnd; // uchwyt okna
  11. cf.lpLogFont = lf; // wskaźnik do struktury LOGFONT
  12. cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS; // flagi: użyj wskaźnika do struktury lpLogFont do zainicjalizowania ustawień; wyświetlanie tylko czcionek wspieranych przez system; wyświetlaj dodatkowe opcje podkreślenia, przekreślenia i wyboru koloru czcionki
  13. if(ChooseFont(&cf)){ // wywołanie okna
  14. *c = cf.rgbColors; // pobieram kolor czcionki
  15. return CreateFontIndirect(lf); // tworzę uchwyt i go zwracam
  16. }
  17. return NULL; // zwracam NULL gdy nie została wybrana żanda czcionka
  18. }

Powyższy fragment kodu wstawiłem wraz z bibliotekami, które wcześniej zostały załączona aby wiadomo było, gdzie funkcję dodać do projektu. Jak widać, jeżeli funkcja ChooseFont zwróci TRUE to zwracam utworzony za pomocą funkcji CreateFontIndirect uchwyt do czcionki. Funkcja GetChooseFont przyjmuje trzy parametry, pierwszym jest oczywiście uchwyt okna rodzica, drugim jest wskaźnik na strukturę typu LOGFONT opisującą czcionkę natomiast trzeci to zmienna 24-bitowa typu COLORREF opisująca kolor w formacie rgb. Zmienna ta będzie używana do zmiany koloru czcionki rysowanej w kontrolce hedit.

Na sam początek w funkcji hwndProc dodać należy takie zmienna:

Listing 3
  1. LRESULT CALLBACK hwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
  2. static RECT wndSize;
  3. static HWND hedit;
  4. static HFONT hf; // uchwyt czcionki
  5. static LOGFONT lf; // struktura opisująca czcionkę
  6. static COLORREF c; // kolor czcionki
  7. static OPENFILENAME ofn;

W powyższym wyrywku kodu opisane zostały komentarzem jedynie te elementy, które zostały dodane. Teraz w komunikacie WM_CREATE musi nastąpić znacząca zmiana:

Listing 4
  1. lf = ncm.lfStatusFont; // tą linijkę trzeba dodać przed wywołaniem funkcji CreateFontIndirect
  2. hf=CreateFontIndirect(&ncm.lfStatusFont); // tutaj było HFONT font = ....
  3. c = RGB(0,0,0); // ustawienie koloru czcionki
  4. SendMessage(hedit, WM_SETFONT, (WPARAM) hf, 0); // tutaj zamiast hf było wcześniej font

Dodać należy do funkcji hwndProc obsługę następującego komunikatu związanego z zmianą koloru czcionki w kontrolce hedit:

Listing 5
  1. case WM_CTLCOLOREDIT: // komunikat umożliwiający zmianę kolorów w kontrolce
  2. {
  3. if(lParam == (LPARAM)hedit){ // jak lParam jest uchwytem okna hedit to
  4. SetTextColor((HDC)wParam, c); // ustawiam kolor dla kontekstu urządzenia zawartego w wParam
  5. }
  6. return NULL; // zwracam null bo nie chcę zmieniać domyślnego koloru tła
  7. }

W komunikacie WM_COMMAND w sekcji związanej z obsługą menu należy dodać kod związany z obsługą kliknięcia dodanej pozycji menu:

Listing 6
  1. switch(LOWORD(wParam)){ // niższe słowo parametru wParam zawiera identyfikator klikniętej pozycji menu
  2. case ID_USTAWIENIA_CZCIONKA: // opcja menu
  3. {
  4. HFONT nf = GetChooseFont(hWnd, &lf, &c); // wywołuję moją funkcję by wyświetlić okno i uzyskać nowy uchwyt czcionki
  5. if(nf){ // jeżeli uchwyt nie jest NULL to
  6. SendMessage(hedit, WM_SETFONT, (WPARAM) nf, 1); // ustawiam czcionkę kontrolki
  7. DeleteObject(hf); // zwalniam uchwyt starej czcionki
  8. hf = nf; // i zapamiętuję uchwyt nowej
  9. }
  10. }
  11. break;

W komunikacie WM_DESTROY przed wywołaniem funkcji PostQuitMessage należy zwolnić uchwyt czcionki:

Listing 7
  1. case WM_DESTROY:
  2. {
  3. DeleteObject(hf);
  4. PostQuitMessage(0);
  5. }
  6. break;

Nowe funkcje i struktury

Lista nowo poznanych funkcji użytych w kodzie programu:

  • ChooseFont - wyświetla okno wyboru czcionki, funkcja ta jest ściśle powiązana z strukturami CHOOSEFONT oraz LOGFONT;
  • DeleteObject - funkcja zwalnia uchwyt czcionki;

Lista nowo poznanych struktur użytych w kodzie:

  • CHOOSEFONT - struktura zawierająca informacje niezbędne do wyświetlenia okna Czcionki za pomocą funkcji ChooseFont;
  • LOGFONT - struktura używana do opisu czcionki.

Komentarze