Obiekty pomocniczeMFC posiada wiele obiektów pomocniczych, które nie są w żaden sposób związane z architekturą programów pisanych przy użyciu...
Pokaż mi serce nie opętane zwodniczymi marzeniami, a pokażę ci człowieka szczęśliwego.
Klasy, takie jak: CFile lub CString, mogą Ci jednak bardzo ułatwić tworzenie programów. Oczywiście nie będziesz musiał używać tych klas, jeśli nie będzie Ci to do niczego potrzebne. W końcu możesz przetwarzać łańcuchy znaków za pomocą normalnych tablic znakowych, a pliki obsługiwać za pomocą klasycznych uchwytów lub strumieni dostępnych w C++. Może tak robić, ale jeśli raz przyzwyczaisz się do korzystania z klas MFC, zapewne będziesz wolał ich używać.Jedną z największych zalet MFC jest fakt, iż biblioteka ta zna swoje własne możliwości i ograniczenia. MFC zdaje sobie sprawę z tego, że nie jest w stanie zrobić wszystkiego, i że od czasu do czasu będziesz musiał skorzystać bezpośrednio z API systemu Windows lub z funkcji dostępnych w dodatkowej bibliotece DLL. Dlatego też niektóre klasy mogą być bardzo łatwo konwertowane na inne, odpowiadające im typy danych stosowanych w programach nie korzystających z MFC.
Doskonałym przykładem takiego działania jest klasa CString. Obiekty tej klasy doskonale wiedzą w jaki sposób mogą zostać zamienione w stały wskaźnik na znak. Oznacza to że obiektów klasy CString możesz używać wszędzie tam, gdzie wcześniej używałeś wskaźnika na niemodyfikowalny łańcuch znaków. Takiego łańcucha znaków nie możesz zmodyfikować, gdyż klasa CString nie byłaby w stanie określić długości łańcucha. Swoją drogą, jeśli będziesz potrzebował dostępu do wskaźnika na znak, którego zawartość możesz zmodyfikować, to możesz posłużyć się metodą GetBuffer, określając jednocześnie ilość znaków, na której będzie można operować.
Innym przykładem klas, które bardzo łatwo można poddawać konwersjom, są klasy CRect, CPoint oraz CSize. Klasy te wyprowadzone zostały ze struktur danych używanych w systemie Windows - RECT, POINT oraz SIZE. Nic nie stoi na przeszkodzie, aby klasa była wyprowadzona ze struktury - jest to jak najbardziej legalne. Cały kruczek wymienionych powyżej klas polega na tym, iż MFC nie dodaje do nich żadnych dodatkowych składowych - ani danych ani funkcji wirtualnych. Dzięki temu, instancje tych klas w C++ będą identyczne jak struktury definiowane w C. Oznacza to, że możesz taktować RECT jako CRect, i na odwrót. Jest to bardzo wygodne. Jednakże ze względu na to, iż klasy te nie mają funkcji wirtualny, nie działają one jak większość klas MFC (patrz sekcja Pomoc ze strony klasy CObject, znajdująca się w dalszej części rozdziału).
Obiekty klasy CWnd
Spośród wszystkich obiektów pomocniczych, żadne nie są tak istotne, jak obiekty klasy CWnd. Klasa ta używana jest w MFC jako reprezentacja wszystkich okien (w tym widoków oraz ramek, które także są wyprowadzone z tej klasy).
Pracując z obiektami tej klasy musisz być świadomy kilku rzeczy. Po pierwsze, nie myśl o tych obiektach jako o rzeczywistych oknach, gdyż nimi nie są. Są one obiektami C++ zawierającymi okna. Ja przyzwyczaiłem się do myślenia o obiektach klasy CWnd jako o butelkach. Gdy stworzysz butelkę, jest ona początkowo pusta. Butelkę tę możesz wypełnić - stworzyć w niej nowe okno - używając do tego odpowiednich funkcji (Create, DoModal lub LoadFrame). Możesz także skojarzyć istniejące już okno z obiektem klasy CWnd.
Załóżmy, że dysponujesz uchwytem do okna, i że chciałbyś taktować go jako obiekt klasy CWnd. Jeśli potrzebujesz go tylko na chwilkę, wskaźnik do obiektu CWnd możesz uzyskać za pomocą statycznej metody CWnd::FromHandle. Jeśli okno ma już odpowiadający mu obiekt klasy CWnd, metoda FromHandle zwraca wskaźnik do tego obiektu. Jeśli okno nie ma skojarzonego z nim obiektu MFC, metoda ta powoduje stworzenie tymczasowego obiektu skojarzonego z tym oknem. Pamiętaj jednak, że takie obiekty klasy CWnd nie obsługują żadnych komunikatów. Co więcej - MFC automatycznie usunie taki obiekt niedługo po zakończeniu obsługiwania aktualnego komunikatu. Nie możesz więc zapamiętać takiego wskaźnika i używać go później.
Jeśli chcesz skojarzyć okno z obiektem klasy CWnd w bardziej trwały sposób, musisz użyć metody SubclassWindow (lub SubclassDlgltem). Metoda ta kojarzy okno 7. obiektem klasy CWnd, aktywuje pętlę obsługi komunikatów i pozwala Ci na pracę z tak stworzonym obiektem, jak gdyby został on stworzony przez MFC.
Jak widać, łatwo jest przekształcić uchwyt do okna w obiekt klasy CWnd. Przekształcenie w przeciwnym kierunku jest jeszcze łatwiejsze. Uchwyt do okna jest zawsze przechowywany w publicznej zmiennej składowej m_hWnd klasy CWnd. Jest to kolejny przykład, ilustrujący jak MFC umożliwia współpracę ze standardowymi funkcjami AP1 systemu Windows.
Stworzenie obiektu klasy CWnd nie jest tym samym, co stworzenie okna. Proces ten określany jest mianem “tworzenia dwuetapowego". Polega ono na tym, iż w pierwszej kolejności tworzysz obiekt C++, a następnie wywołujesz metodę Create (lub inną) w celu stworzenia okna skojarzonego z obiektem klasy CWnd. Takie postępowanie zapewnia klasie CWnd maksymalną elastyczność. Pozwala ono na tworzenie zupełnie nowych okien lub kojarzenie okien już istniejących z obiektami klasy CWnd. Co więcej, kod służący do tworzenia okien umieszczony jest wewnątrz funkcji, co pozwala na łatwe zasygnalizowanie powstania błędu. Jak wiadomo, w języku C++ konstruktory klas nie mogą zwracać żadnych wartości, co utrudnia sygnalizowanie powstania błędu podczas działania konstruktora.