Podstawowe informacje o Visual C++ i MFC


Wstęp

Powyższa strona stanowi krótkie omówienie podstawowych cech i możliwości środowiska programistycznego Visual C++ oraz  biblioteki MFC (ang. Microsoft Foundation Class).
Tworząc powyższy opis oparto się na środowisku Microsoft Visual C++ 5.0. Przedstawione informacje zachowują swoją ważność również dla najnowszego pakietu z serii Visual C++ w wersji 6.0, którego narzędzia i idea działania stanowią jedynie poszerzenie poprzedniej wersji tego programu.

Tworząc powyższy opis oparto się na środowisku Microsoft Visual C++ 5.0. Przedstawione informacje zachowują swoją ważność również dla najnowszego pakietu z serii Visual C++ w wersji 6.0, którego narzędzia i idea działania stanowią jedynie poszerzenie poprzedniej wersji tego programu.

Co wchodzi w skład pakietu Visual C++?

Podstawową aplikacją wchodzącą w skład pakietu Visual C++ 5.0 jest Microsoft Developer Studio 97 tworzące zintegrowane środowisko projektowe zawierające takie elementy jak:

W skład pakietu wchodzą również różnego rodzaju narzędzia pomocnicze, ułatwiające tworzenie i testowanie aplikacji. Poniżej przedstawiono wybrane narzędzia:

Nazwa narzędzia Przeznaczenie
Spy++ Udziela wyczerpujących informacji o wszystkich aktualnie działających procesach, wątkach, otwartych w nich oknach i elementach kontrolnych.
Process Viewer Application Podaje podstawowe informacje o działających aplikacjach (nazwa procesu, identyfikator, priorytet, bitowość, ścieżkę do pliku wykonywalnego), umożliwia również "zabicie" procesów z nimi związanych.
InstallShield Pozwala na łatwe wygenerowanie wersji instalacyjnych stworzonych aplikacji.
ActiveX Control Test Container Umożliwia testowanie kontrolek ActiveX.
OLE-COM Object Viewer Testowanie obiektów (a w szczególności kontrolek) OLE.
Help Workshop Środowisko wspomagające tworzenie systemu pomocy w aplikacjach.

Typy kodu generowane przez Visual C++

Począwszy od wersji 5.0 Visual C++ generuje kod 32-bitowy przeznaczony dla środowiska Win32 obejmującego systemy operacyjne Windows 95/98/NT. Visual C++ pozwala na stworzenie różnorodnego kodu wynikowego, generuje między innymi:

MFC Application Aplikacje okienkowe korzystające z biblioteki MFC.
MFC Dynamic-Link Library Biblioteki DLL będące rozszerzeniem zbioru klas MFC.
MFC ActiveX Control Kontrolki ActiveX.
Win32 Application Aplikacje okienkowe nie działające bez wykorzystania klas MFC.
Win32 Console Application Aplikacje konsoli Win 32 (Tryb MS-DOS).
Win32 Dynamic-Link Library Standardowe biblioteki DLL.
Win32 Static Library Biblioteki statyczne (Lib).

Tworzenie kodu dla aplikacji, bibliotek DLL i kontrolek opartych o klasy MFC jest wspomagane przez kreatory (ang. wizards) automatycznie generujące dużą część kodu źródłowego.

W środowisku Visual C++ projekty umieszczone są w tzw. obszarach roboczych (ang. workspace). W pojedynczym obszarze roboczym może być zawartych kilka projektów co pozwala na sprawne zarządzanie przygotowaniem złożonych aplikacji np. przestrzeń robocza może zawierać dwa projekty będące bibliotekami DLL oraz jeden będący aplikacją MFC wykorzystującą funkcje zdefiniowane w tych bibliotekach.

Podstawowe kreatory

W pakiecie Visual C++ został rozwinięty system tzw. kreatorów (ang. wizards), które automatycznie generują duże fragmenty kodu obsługującego standardowe elementy aplikacji. Kod ten stanowi punkt wyjścia do tworzenia własnych programów. Podczas tworzenia aplikacji korzystających z biblioteki MFC wykorzystuje się najczęściej dwa opisane poniżej kreatory.

MFC AppWizard (exe)

AppWizard jest kreatorem tworzącym szkielet aplikacji okienkowej korzystającej z biblioteki MFC. Generuje aplikacje początkową składającą się z klas aplikacji, okna głównego, dokumentu i widoku. W celu uzyskania informacji o typie aplikacji którą chcemy wygenerować AppWizard pyta o szereg informacji związanych z tworzonym projektem. Podstawowe dane, które należy wprowadzić to:

Po wyspecyfikowaniu powyższych danych kreator podaje informacje o tym jakie klasy zostaną wygenerowane i w jakich plikach będą umieszczone. W stworzonym kodzie AppWizard używa we wstawionych komentarzach zwrotu "TODO:" do wskazania fragmentów, które powinny zostać zmodyfikowane lub uzupełnione.

MFC ClassWizard

ClassWizard służy do dwóch podstawowych zadań. Pierwszym z nich jest tworzenie klas powiązanych z takimi zasobami jak okna dialogowe, paski narzędziowe itp., do których następnie zostaną dodane metody obsługi elementów kontrolnych.
Drugim zadaniem kreatora klas jest powiązanie komunikatów systemu Windows z obsługującymi je metodami poprzez aktualizacje mapy komunikatów (ang. message map) m.in. kojarzącej pozycje menu z funkcjami ich obsługi. W pewnym uproszczeniu można powiedzieć, że ClassWizard tworzy funkcje wywoływane automatycznie gdy do zawierającej je klasy dotrze skojarzony z nimi komunikat. W celu dodania procedury obsługi zdarzenia należy na rozwijanej liście "Class name" wybrać klasę do, której ma zostać dodana procedura a następnie z listy "Messages" wybrać komunikat który zostanie z nią powiązany; kreator automatycznie wygeneruje szkielet funkcji.

 

Standardowe pliki tworzące projekt aplikacji

Osoby pierwszy raz stykające się z pakietem Visual C++ może dziwić duża ilość różnorakich plików składających się na standardowy projekt aplikacji wygenerowanej przez AppWizarda. Pliki te gromadzą informacje niezbędne dla prawidłowego działania kompilatora oraz przechowują obiekty stworzone przez kreator aplikacji.
Poniżej przedstawiono opis zawartości podstawowych plików wygenerowanych przez kreator MFC AppWizard (exe) tworzących przykładowy projekt aplikacji typu SDI o nazwie "Nowy".

Nowy.dsw Developer Studio Workspace File - plik, generowany i modyfikowany przez Developer Studio (Visual Studio), przechowujący informacje o obszarze roboczym w formacie tekstowym.
Nowy.dsp Developer Studio Project File - plik przechowujący informacje o projekcie. Plik również nie przeznaczony do samodzielnej edycji.
Nowy.ncb Plik zawierający ustawienia środowiska programistycznego.
Nowy.h, Nowy.cpp Deklaracje oraz ciało klasy CNowyApp (rdzeń aplikacji).
MainFrm.h, MainFrm.cpp Deklaracje oraz ciało klasy CMainFrame (główne okno ramowe aplikacji).
NowyDoc.h, NowyDoc.cpp Deklaracje oraz ciało klasy CNowyDoc (klasa dokumentu).
NowyView.h, NowyView.cpp Deklaracje oraz ciało klasy CNowyView (klasa widoku).
Nowy.clw Informacje używane przez kreator klas przy edycji i tworzeniu nowych klas, map komunikatów oraz map dialogów.
StdAfx.h, StdAfx.cpp Używane przez kompilator do budowania pliku prekompilowanych nagłówków (PCH).
Resource.h Identyfikatory zasobów.
Nowy.rc Listing zasobów Microsoft Windows używanych przez program (ikony, mapy bitowe, kursory) i przechowywanych w podkatalogu res.
res Podkatalog zawierający zasoby aplikacji.

 

Co to jest MFC ?

Wraz z pakietem Visual C++ dostarczana jest biblioteka MFC (ang. Microsoft Foundation Class), której klasy stanowią "szkielet aplikacji" dla programów pracujących w systemie Windows. Napisane w języku C++ klasy MFC zawierają bardzo dużo kodu potrzebnego do zarządzania oknami, elementami menu i dialogami; zapewniają podstawowe operacje wejścia/wyjścia i dostarczają gotowe struktury danych: listy, kolekcje itp.
Wszystkie fragmenty kodu potrzebne do spełnienia specyficznych wymagań dotyczących danej aplikacji są dodawane do kodu "szkieletowego". Dzięki dużym możliwością języka C++ (dziedziczenie, przeciążanie metod, funkcje wirtualne itp.) modyfikacja kodu jest naturalna i łatwa.
MFC znacznie skraca czas tworzenia oprogramowania dla Windows, ułatwia dostęp do baz danych dzięki technikom DAO (ang. Data Access Objects) i ODBC (ang. Open Database Connectivity), pozwala na łatwe oprogramowanie komunikacji sieciowej przy wykorzystaniu tzw. gniazd (ang. sockets).
Biblioteki MFC 1.0 do 2.5 była rozwijana w oparciu o system operacyjny Windows 3.1x, kolejne wersje biblioteki były przeznaczone dla systemów Windows 95 i NT. Środowisko Visual C++ 5.0 zawiera bibliotekę MFC w wersji 5.0 (choć oznaczenie pliku DLL może sugerować wersję 4.2).

Klasy MFC zostały utworzone w oparciu o interfejs do programowania aplikacji API (ang. Application Programming Interface) stanowiący część systemu operacyjnego Windows. API jest biblioteką funkcji napisanych w języku C. Aplikacje nie korzystające ze szkieletu takiego jak MFC używają bezpośrednio funkcji API, taki sposób programowania wymaga jednak dużego nakładu pracy i szerokiej wiedzy o API.

 

Jaka jest idea działania MFC ?

Dla osób, które nigdy wcześniej nie spotkały się z biblioteką MFC pokazano poniżej ideę jej wykorzystania. Przed przeczytaniem dalszego tekstu zalecamy zapoznanie się z hierarchią klas MFC.

Przykładowo w każdej aplikacji MFC klasa CWnd jest klasą bazową dla wszystkich obiektów będących oknami, czyli również dla okien dialogowych, widoków i elementów sterujących. Z klasy CWnd jest wydziedziczona klasa CFrameWnd zawierająca wszystkie standardowe funkcje potrzebne dla prawidłowego działania okna ramowego. Z klasy tej zawsze wyprowadza się klasę okna głównego aplikacji. W ten sposób obiekt klasy okna głównego dziedziczy standardowe zachowanie od CFrameWnd, ale również może zawierać dodatkowe cechy zdefiniowane przez nowo dodane metody. Dodatkowo zachowanie przejęte dzięki dziedziczeniu funkcje klasy CFrameWnd może zostać zmodyfikowane poprzez zastąpienie ich swoimi funkcjami.

 

Złożone struktury danych zaimplementowane w MFC

Dla osób, które po raz pierwszy spotkały się z biblioteką MFC ważną może okazać się informacja, że biblioteka ta posiada zaimplementowane, gotowe do użycia struktury danych (tablice, listy i mapy), nazywane dalej klasami kolekcji. Korzystanie z dostarczonych klas jest bardzo dużym ułatwieniem, gdyż wyręcza programistę z konieczności żmudnej implementacji typowych struktur danych. Używanie kolekcji pozwala na przechowywanie i przetwarzanie grup zmiennych określonego typu standardowego lub całych obiektów. Ponieważ kolekcje są wyprowadzone z klasy CObject możliwe jest wykorzystanie mechanizmu serializacji do zapisu i odczytu danych w nich zawartych.
Poniżej przedstawiono krótki opis podstawowych kolekcji.

Typ kolekcji Opis
Tablice Tablice z indeksami całkowitoliczbowymi o rozmiarach zmieniających się w sposób dynamiczny (nie ma konieczności kontroli właściwej długości tablicy); w zależności od typów przechowywanych obiektów rozróżniamy następujące klasy tablic: CByteArray, CWordArray, CDWordArray (odpowiednio wartości typu BYTE - 1 bajt, WORD - 2 bajty np. unsigned int, DWORD - 4 bajty np. float, long), CPtrArray (wskaźniki typu void), CStringArray (obiekty typu CString).
Listy Uporządkowane, nieindeksowane listy elementów pozwalające na dodawanie i usuwanie elementów, umożliwiają dostęp do dowolnych elementów poprzez iterację listy; przykładem klas implementujących listy są: CPtrList (przechowuje wskaźniki typu void), CObList (wskaźniki do obiektów), CStringList (obiekty typu CString).
Mapy Mapa przechowuje logiczne powiązania pomiędzy dwoma elementami różnego typu; pierwszy obiekt tego powiązania (pole wyszukania) jest niepowtarzalnym kluczem, drugi obiekt przechowuje właściwe dane; taka kombinacja zapewnia bardzo szybkie zapamiętywanie i pobieranie danych; mapy tak jak listy umożliwiają dostęp do elementów poprzez zastosowanie iteratorów; dostępne są następujące mapy: CMapWordToPtr (klucz typu WORD, danymi są wskaźniki typu void), CMapStringToPtr (klucz typu CString, dane wskaźnik typu void), CMapPtrToWord, CMapPtrToPtr, CMapWordToOb, CMapStringToOb i CMapStringToString.

Korzystanie z wymienionych klas ułatwiają szablony (ang. templates) tablic, list i map będące "opakowaniem" (ang. wrapper) dla obiektów tych kolekcji. Dostępne są szablony CTypedPtrArray, CTypedPtrList i CTypedPtrMap.
Poniżej przedstawiono przykładowy sposób korzystania z szablonu CTypedPtrList.

// Dołączenie odpowiedniego pliku nagłówkowego //

#include <afxtempl.h>



// Tworzenie listy o nazwie MyList przechowującej

// wskaźniki do obiektów klasy MyClass

CTypedPtrList<CObList, MyClass*> MyList;



// Iteracja listy //

MyClass *pElement;

POSITION pos;

for(pos = MyList.GetHeadPosition(); pos; )

{

    pElement = MyList.GetNext(pos);



    ...

}

Wszystkie przedstawione klasy kolekcji wymagają dołączenia do kodu źródłowego pliku nagłówkowego afxcoll.h, zaś szablony afxtempl.h. Szczegółowy opis przedstawionych klas i metod z nimi związanych można znaleźć w plikach pomocy pakietu Visual C++.

 


Strona główna