Ludzie pragną czasami się rozstawać, żeby móc tęsknić, czekać i cieszyć się z powrotem.
2, na pasku dialogowym można umieszczać nie tylko przyciski, lecz także inne elementy kontrolne. Dlaczego w takim razie, większość programistów cały czas stosuje tradycyjne paski narzędzi? Istnieje ku temu kilka powodów. Po pierwsze, kreator App Wizard automatycznie generuje pasek narzędzi przy tworzeniu programu. Po drugie, w systemie Windows 3.1 (a także w nieco mniejszym stopniu, w systemie Windows 95) posiadanie paska dialogowego z dużą ilością elementów kontrolnych w dużym stopniu wyczerpuje zasoby systemu. Standardowe paski narzędzi zużywają znacznie mniej zasobów. Ostatnim powodem jest to, że pasków dialogowych nie można zakotwiczyć przy wszystkich krawędziach okna aplikacji. Wynika to z prostego faktu, że MFC nie wie, w jaki sposób należy obracać wyświetlane elementy kontrolne (obracanie bitmap jest znacznie prostsze).
Aby zrozumieć, na czym polega problem obracania pasków dialogowych, spróbuj przeciągnąć dowolny pasek narzędzi wyświetlony pod paskiem menu programu (na przykład Developer Studio) i umieścić go przy prawej krawędzi okna. Pasek narzędzi zostanie obrócony, dostosowując się do nowego położenia. Teraz spójrz na rysunek 5.3. Przedstawia on wygląd programu z rysunku 5.2 po przeciągnięciu paska dialogowego i zakotwiczeniu go przy lewej krawędzi okna. Nie jest to ładny widok, prawda?
Aby zapobiec takim sytuacjom, podczas dodawania paska dialogowego Galeria Komponentów umożliwi Ci określenie krawędzi ekranu, przy której tworzony pasek zostanie umieszczony. Wybranie jednej z krawędzi spowoduje, iż pasek będzie mógł być zakotwiczony tylko przy niej lub przy drugiej, równoległej krawędzi. Musiałem zmodyfikować kod umieszczony w klasie CMainFrame, aby móc sporządzić rysunek 5.3, gdyż normalne przeciągnięcie i zakotwiczenie paska przy tej krawędzi byłoby niemożliwe.
Modyfikowanie pasków narzędzi
Kolejną cechą pasków narzędzi, powodującą, że są one chętniej stosowane niż paski dialogowe, jest udostępnienie możliwości modyfikowania zawartości paska przez użytkownika. No, a przynajmniej coś w tym stylu. Zaraz opowiem całą historię. Otóż starsze wersje MFC udostępniały cały kod potrzeby do tworzenia pasków narzędzi. Nowsze wersje tworzą jedynie “otoczkę" pozwalającą na wykorzystywanie w programie standardowego elementu kontrolnego. To właśnie ten standardowy element kontrolny udostępnia wszystkie narzędzia potrzebne do modyfikowania postaci paska. Jednak ze względu na to, że MFC bardzo się stara, aby obiekty klasy CToolBar wyglądały tak samo jak dotychczas, niezwykle trudno jest udostępnić użytkownikowi narzędzia do modyfikacji paska. Fakt, jest to zadanie trudne, ale nie niemożliwe.
Jakie sposoby modyfikowania pasków narzędzi są dostępne? Otóż istnieją narzędzia pozwalające na przesuwanie przycisków w obrębie paska (należy w tym celu wcisnąć przycisk Shift i przeciągnąć przycisk za pomocą myszki). Jeśli przeciągniesz przycisk poza powierzchnię paska narzędzi i upuścisz, przycisk zniknie. Standardowy element kontrolny udostępnia także specjalne okno dialogowe, które pozwala użytkownikowi dodawać, usuwać oraz zmieniać kolejność przycisków na pasku narzędzi. Dodatkowo paski narzędzi dysponują także metodami pozwalającym na zapisanie ich stanu w rejestrze systemowym i późniejsze jego odtworzenie.
Wszystkie problemy z klasą CToolBar wynikają z faktu, iż jest ona “jednokierunkową otoczką" standardowego elementu kontrolnego. Oznacza to, że klasa ta wykorzystuje klasę CToolBarCtrl (standardowy element kontrolny implementujący pasek narzędzi), jednak jakiekolwiek modyfikacje dokonane na elemencie kontrolnym nie będą zauważone i uwzględnione w obiekcie klasy CToolBar. Z tego właśnie powodu, metody służące do zapisywania i odczytywania postaci paska z rejestru systemowego, są całkowicie bezużyteczne, gdyż po powtórnej inicjalizacji paska, modyfikacje wcześniej w nim dokonane nie zostaną uwzględnione. Jeśli będziesz chciał zapamiętywać i odtwarzać stan paska narzędzi, będziesz musiał stworzyć własne metody umożliwiające poprawne wykonywanie tych operacji.
Umożliwienie wykorzystania innych cech standardowego elementu kontrolnego nie przysparza, na szczęście, większych trudności. Aby umożliwić modyfikowanie postaci paska, wystarczy nadać oknu standardowego elementu kontrolnego styl CCS_ADJUSTABLE, Nie możesz podać tego stylu podczas tworzenia paska narzędzi, gdyż MFC stosuje ten sam styl (jego wartość) do zupełnie innych celów. Możesz go określić już po stworzeniu paska:
::SetWindowsLong(m_wndToolBar.GetToolBarCtrl().m_hWnd,GWL_STYLE, m_wndToolBar.GetToolBar().GetStyleO |CCS^ADJUSTABLE);
Będziesz także musiał obsługiwać niektóre komunikaty WM_NOTIFY przesyłane z paska narzędzi do okna ramki (lub innego okna, w którym umieszczony jest pasek narzędzi). Procedury obsługi tych komunikatów będziesz mógł bez problemów zdefiniować za pomocą makr ON_NOTIFY umieszczonych w mapie komunikatów. Oczywiście kreator Class Wizard nie będzie miał pojęcia co chcesz zrobić, dlatego też makra te będziesz musiał umieścić w mapie komunikatów samodzielnie.
Pełną listę komunikatów wysyłanych przez paski narzędzi możesz znaleźć w elektronicznej dokumentacji dostarczanej wraz z programem Visual C++. W Tabeli 5.3 przedstawione zostały jedynie te komunikaty, które są istotne z punktu widzenia modyfikowania postaci pasków narzędzi omawianych w tym rozdziale (patrz listing 5.7).
Tabela 5.3. Komunikaty powiadamiania generowane przez paski narzędzi.
Komunikat Opis
TBN_QUERYINSERT Czy użytkownik może wstawić ten przycisk?
TBN_QUERYDELETE Czy użytkownik może usunąć ten przycisk?
TBN_GETBUTTONINFO Pobierz informacje o przycisku i umieść je w strukturze TBNOTIFY.
TBN_RESET Przywróć oryginalną postać paska narzędzi.
TBN_TOOLBARCHANGE Pasek narzędzi został zmodyfikowany.
Listing 5.7. Ramka z paskiem narzędzi pozwalającym na modyfikacje swojej postaci.