Rozdzia� 12. Kontrolki W tym rozdziale: Historia kontrolek w Windows Anatomia kontrolki Spos�b wykorzystania standardowych kontrolek Samodzielnie rysowane kontrolki Klasa CButton Klasa CListBox Klasa CEdit Klasa cstatic Klasa CScrollBar Klasa CComboBoK Dostosowywanie kontrolek Obs�uga kontrolek za pomoc� klawiatury W tym rozdziale przyjrzymy si� bli�ej kontrolkom Windows oraz reprezentuj�cym je klasom MFC. Pod koniec rozdzia�u b�dziesz ekspertem w praktycznym ich wykorzystaniu i dostosowywaniu. Wprowadzenie Nowa 32-bitowa wersja Windows jest dostarczana z ponad dwudziestoma rodzajami dost�pnych kontrolek. Sze�� z nich by�o dost�pnych ju� w pierwszej wersji systemu; te kontrolki znajduj� si� w pliku user.exe. Pozosta�e s� nazywane kontrolkami standardowymi (common controls) i znajduj� si� w pliku comctl32.dll. O ile sze�� oryginalnych kontrolek jest dost�pnych we wszystkich wersjach Windows, o tyle kontrolki standardowe s� dost�pne wy��cznie w �rodowiskach 32-bitowych. 284 Cz�� II � Podstawy programowania Windows Kontrolki to okna potomne ograniczone do swoich okien nadrz�dnych. Gdy okno nadrz�dne jest przesuwane, wraz z nim przesuwane s� okna potomne. Podobnie, w momencie niszczenia okna nadrz�dnego s� niszczone r�wnie� okna potomne. Kontrolki i pe�nione przez nie funkcje s� reprezentowane przez r�ne klasy MFC. Kontrolka listy jest reprezentowana przez klas� CListBox, kontrolka pola edycji przez klas� CEdit itd. Sze�� oryginalnych kontrolek, odpowiadaj�ce im klasy MFC oraz klasy okien zosta�y zebrane w tabeli 12.1. Tabela 12.1. Klasy oryginalnych kontrolek Windows Kontrolka Klasa MFC lasa Windows(WNDCLASS) Przycisk (Button), Cbutton BUTTON Lista (List Box) CListBox LISTBOK Rozwijana lista (Combo Box) CComboBox COMBOBOK Pole edycji (Edit Control) CEdit Element statyczny (Static Control) CStatic STATIC Pasek przewijania (Scroll Bar) CScrollBar CROLLBAR Poniewa� kontrolki to wyspecjalizowane okna, MFC wyprowadza klasy kontrolek z bazowej klasy cwnd. Korzy�ci� wyprowadzenia klas kontrolek z jednej klasy bazowej jest to, �e w wielu przypadkach ta sama czynno�� w odniesieniu do r�nych kontrolek mo�e by� wykonana przez wywo�anie tej samej funkcji sk�adowej, tak wi�c ctl->SetwindowText ( (char*) "Hello") zar�wno ustawia tekst wy�wietlany na przycisku, jak i wstawia napis "Hello" do kontrolki pola edycji. Tworzenie kontrolek Kontrolki mo�na tworzy� na dwa sposoby. Jeden z nich polega na wstawieniu kontrolki do zasob�w okna dialogowego. W momencie �adowania zasobu dialogu Windows automatycznie tworzy odpowiednie obiekty kontrolek. Kreatory wbudowane w Yisual Studio sprawiaj�, �e jest to wprost trywialnie �atwe. Gdy zako�czysz projektowanie okna dialogowego, mo�esz uruchomi� ClassWizarda, kt�ry wygeneruje ca�y kod potrzebny do dzia�ania kontrolek. ClassWizard umo�liwia tak�e powi�zanie (i to cho�by za pomoc� jedynie myszy) kontrolek z funkcjami pochodz�cych od nich komunikat�w. Druga metoda polega na jawnym wywo�aniu funkcji tworz�cej kontrolk�. Je�li zechcesz utworzy� kontrolk� listy, wywo�anie tej funkcji mog�oby wygl�da� na przyk�ad tak: m_ListBox.Create(WS_CHILD | WS_VISIBLE | WS VSCROLL, ctlRect, this, IDC LIST1) Grupa sta�ych tworz�cych pierwszy parametr, WS_CHILD, WS_VISIBLE oraz WS_VSCROLL to znaczniki stylu okre�laj�ce wygl�d i spos�b dzia�ania kontrolki. W tym przypadku okre�laj� one, �e kontrolka powinna zosta� utworzona jako widoczne okno potomne posiadaj�ce pionowy pasek przewijania. Nast�pny parametr, ctiRect, to obiekt klasy CRect okre�laj�cy po�o�enie i rozmiary listy. Kolejny parametr, this, jest wska�nikiem do okna nadrz�dnego. W�a�nie dzi�ki niemu MFC jest w stanie ustanowi� relacje zale�no�ci pomi�dzy oknami. Ostatni z parametr�w, IDC_LISTI, jest liczb� ca�kowit� bez znaku reprezentuj�c� identyfikator zasobu kontrolki. Gdy jawnie tworzysz kontrolk�, u�ywaj�c funkcji Create, musisz j� r�cznie umie�ci� w oknie nadrz�dnym. Po�o�enie i rozmiar kontrolki okre�la prostok�t otaczaj�cy zdefiniowany w obiekcie klasy CRect. Gdy obliczasz rozmiary kontrolki podczas jej tworzenia, zawsze we� pod uwag� wysoko�� i szeroko�� bie��cej czcionki. W przeciwnym razie napisy w kontrolce mog� by� obci�te, a sama kontrolka mo�e znale�� si� w niew�a�ciwym miejscu okna nadrz�dnego. Pami�taj tak�e, �e po�o�enie kontrolki w oknie nadrz�dnym okre�la si� zawsze wzgl�dem pocz�tku obszaru roboczego okna, tak jak pokazano na listingu 12.1. Listing 12.1. Okre�lanie po�o�enia kontrolki CClientDC dc (this); CFont TempFont; TEKTMETRIC metric; CRect TempRect; CEdit TempEdit; // Pobieramy wymiary urz�dzenia wyj�ciowego i zamieniamy je na punkty CharHeight = -((dc.GetDeviceCaps(LOGPIKELSY)*8/72)); // Tworzymy czcionk� TempFont.CreateFont(CharHeight, O, O, O, FW_NORMAL, O, O, O, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFUALT_QUALITY, DEFAULT_PITCH | FFJDONTCARE, "Arial"); // Wybieramy czcionk� w kontek�cie urz�dzenia obszaru roboczego // (z zachowaniem aktualnie wybranej czcionki) CFont *p01dFont = dc.SelectObject(&TempFont); // Pobieramy rozmiary nowej czcionki dc.GetTextMetrics(smetric); CharX = metric.tmAveCharWidth; CharY = metric.tmHeight+metric.tmExternalLeading; // Obliczamy wymiary prostok�ta otaczaj�cego kontrolk� TempRect.SetRect(CharX*2, CharY*2, CharX*20, CharY*2); // Tworzymy kontrolk� TempEdit.Create(WS_CHILD | WS_VISIBLE, TempRect, this, IDC EDIT1); Ten fragment kodu ilustruje zmian� czcionki obszaru roboczego na Arial, a nast�pnie wykorzystanie jej wymiar�w w celu ustalenia po�o�enia kontrolki w obszarze roboczym. Najpierw pobieramy rozmiary obszaru roboczego okna i zamieniamy je z pikseli na cal logiczny na punkty. Poniewa� rozmiary monitor�w s� r�ne, Windows podaje szeroko�� ekranu w tzw. calach logicznych. Cal logiczny jest jednostk� miary niezmienn� baz wzgl�du na rozmiar obrazu i jest do�� cz�sto u�ywany w kodzie s�u��cym do okre�lania po�o�enia okien, gdy� umo�liwia programi�cie okre�lenie pozycji na ekranie bez wzgl�du na rzeczywisty rozmiar obrazu. Jednak aby zastosowa� t� jednostk� w naszych operacjach z rozmiarami czcionki, musimy zamieni� j� na tak� jednostk� miary, kt�rej mo�emy u�y�, czyli w tym przypadku na punkty. Gdy ju� mamy obliczon� wysoko�� znak�w, mo�emy u�y� jej do stworzenia egzemplarza czcionki Arial w obiekcie klasy CFont. Po utworzeniu czcionki musimy wybra� j� w bie��cym kontek�cie urz�dzenia. Wywo�anie CDC: : Selectobject () wybiera now� czcionk� w kontek�cie urz�dzenia obszaru roboczego okna. Gdy mamy czcionk� wybran� w kontek�cie urz�dzenia, za pomoc� funkcji CDC: :GetTextMetrics (), wype�niaj�c struktur� TEKTMETRIC, mo�emy odczyta� informacje o wysoko�ci i szeroko�ci czcionki. U�ywaj�c p�l tej Struktury, tmAveCharWidth, tmHeight oraz tmExternal-Leading, mo�emy obliczy� wysoko�� i �redni� szeroko�� pojedynczego znaku. Po wykonaniu ca�ej tej pracy jeste�my prawie gotowi do stworzenia kontrolki. Znaj�c wysoko�� i szeroko�� pojedynczego znaku, mo�emy u�y� ich do obliczenia wymiar�w prostok�ta (zawartego w obiekcie klasy CRect) i u�ycia go do okre�lenia po�o�enia kontrolki. Wywo�uj�c funkcj� CRect: :SetRect (), definiujemy prostok�t o lewym g�rnym rogu w miejscu o wsp�rz�dnych 2,2 oraz szeroko�ci 20 i wysoko�ci 2 znaki. Gdy u�yjemy go przy tworzeniu kontrolki pola edycji, spowoduje on utworzenie kontrolki dwa znaki na prawo od lewej kraw�dzi i dwa znaki poni�ej g�rnej kraw�dzi obszaru roboczego. Szeroko�� kontrolki wyniesie dwadzie�cia przeci�tnych znak�w, za� jej wysoko�� - dwa znaki. Przy konstruowaniu kontrolki w podany spos�b objawia si� pewna interesuj�ca, cho� czasem do�� denerwuj�ca �w�a�ciwo��" Windows. Je�li kontrolka zostanie wstawiona jako cz�� zasobu dialogu, jest rysowana tak, jakby zosta�a �wyrze�biona" na powierzchni okna dialogowego. Takie kontrolki nosz� nazw� kontrolek z tr�jwymiarow� ramk� (3D border). W kontrolkach tworzonych automatycznie nie stosuje si� automatycznie tego efektu i s� one rysowane z dwuwymiarow� ramk� (2D border). O tworzeniu tr�jwymiarowej ramki decyduje znacznik stylu WS_EX_CLIENTEDGE. Jak wskazuje przedrostek WS_EX, jest to znacznik rozszerzonego stylu kontrolki. Jednak omawiana przed chwil� funkcja Create () nie daje mo�liwo�ci okre�lenia rozszerzonego stylu. Jak wi�c mo�na rozwi�za� ten problem? Klasa cwnd, z kt�rej zosta�o wyprowadzonych sze�� oryginalnych kontrolek, posiada tak�e funkcj� sk�adow� CreateEx (), przyjmuj�c� znaczniki stylu rozszerzonego. Wywo�anie tej funkcji zamiast funkcji createo w listingu 12.1 wygl�da�oby tak: TempEdit.CreateEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD i WS_VISIBLE. TempRect, this, IDC_EDIT1); Jak wida�, sk�adnia funkcji CreateEx () r�ni si� nieco od sk�adni funkcji Create (). Pierwszy argument okre�la rozszerzony styl okna, taki jak WS_EX_CLIENTEDGE. Drugi argument okre�la klas� okna (WNDCLASS) kontrolki, kt�r� w tym przypadku jest EDIT. Czwarty argument zawiera nazw� okna; w przypadku tworzenia kontrolek powiniene� przekaza� warto�� NULL. Pi�ty, sz�sty, si�dmy i �smy argument okre�laj�, odpowiednio, znaczniki standardowego stylu, prostok�t otaczaj�cy w obiekcie CRect, wska�nik do okna nadrz�dnego oraz identyfikator zasobu kontrolki. Jak dot�d poznali�my podstawy tworzenia kontrolek. Dowiedzieli�my si� jak tworzy� kontrolki w oknach dialogowych oraz r�cznie, w oknach nadrz�dnych. By� mo�e zastanawiasz si�, w jaki spos�b dosta� si� do informacji zawartych w kontrolce. Je�li kon-trolkajest cz�ci� zasob�w dialogu, dost�pem do danych kontrolki zarz�dza mechanizm nazywany DDX (Dialog Data Exchange - wymiana danych dialogu). Zajmiemy si� nim szczeg�owo w rozdziale 14. Je�li jednak kontrolka jest cz�ci� zwyk�ego okna, w celu dost�pu do jej danych musisz skorzysta� z funkcji sk�adowych kontrolki. W nast�pnych sekcjach zapoznamy si� wi�c ze szczeg�ami programowania ka�dej z sze�ciu oryginalnych kontrolek. U�ywanie klasy CButton Klasa CButton s�u�y do tworzenia przycisk...
Morfeusz__