C dla kaûdego (cz. 4.) ---------------------- OTWIERANIE EKRANÓW Umiecie juû otwieraê okna na ekranie Workbencha (a wîaôciwie na standardowym ekranie publicznym). Dziô nauczymy Was otwieraê okna na cudzych ekranach oraz... samemu otwieraê ekrany. Kamil Iskra, Dariusz Ûbik Wîaôciwie to wypadaîoby zaczâê od tego, czym sië róûni okno od ekranu, bo, jak zauwaûyliômy, autorzy wielu artykuîów w polskiej prasie komputerowej po prostu mylâ te dwa pojëcia. Czym jest okno, tîumaczyê chyba nie trzeba. "Takie coô" majâce zwykle ramkë i kupë gadûetów. Wystarczy zresztâ uruchomiê któryô z przykîadów z poprzedniej czëôci, aby je zobaczyê. Ekrany sâ zaô jednostkâ nadrzëdnâ w stosunku do okien -- okno otwiera sië na konkretnym ekranie i nie moûna go za pomocâ myszy przesunâê na inny. Ekrany obsîuguje sië tylko dwoma gadûetami: przesuwa w górë/w dóî (sîuûy do tego po prostu listwa tytuîowa) oraz do przodu/do tyîu. Wszystkie inne gadûety, jakie moûna zobaczyê, znajdujâ sië w oknach. Ekranów, w przeciwieïstwie do okien, nie moûna zwykle przesuwaê na boki -- wyjâtkiem sâ te o szerokoôci innej niû szerokoôê aktualnego trybu wyôwietlania. Kaûdy ekran ma wîasne, niezaleûne od innych, atrybuty, takie jak liczba kolorów i ich numery (bo trzeba wiedzieê, ûe kolory sâ numerowane), a takûe szerokoôê, wysokoôê i tryb wyôwietlania (tj. czëstotliwoôê odchylania pionowego/poziomego, przeplot itp.). Okna otwarte na danym ekranie dziedziczâ jego atrybuty, tzn. majâ takie same kolory jak ekran, sâ wyôwietlane w takiej samej rozdzielczoôci itp. No, chyba wystarczy tego sadzenia banaîów. Ci, którzy jeszcze majâ wâtpliwoôci, czym sië jedno od drugiego róûni, niech sobie poczytajâ instrukcjë do Amigi. Tam jest to nieúle opisane i pokazane na obrazkach. Zacznijmy moûe od otwierania naszych okien na cudzych ekranach. Przede wszystkim, nie na kaûdym ekranie moûna okno otworzyê -- do tego celu sîuûâ ekrany publiczne (ang. public screens). Domyôlnym ekranem publicznym jest ekran Workbencha. Jeôli chcemy otworzyê okno na innym ekranie publicznym, to musimy znaê nazwë tego ekranu. Jest ona zwykle wyôwietlana na listwie tytuîowej okna bâdú w "About". Przykîady: "CygnusEdScreen1", "DOPUS.1", "GOLDED.1", "SC_CPR.1". Pisownia maîych i duûych liter JEST WAÛNA! Najpierw warto sprawdziê, czy ekran publiczny o danej nazwie istnieje. Sîuûy do tego funkcja: struct Screen *LockPubScreen( UBYTE *name ); Jej parametrem jest wskaúnik na nazwë ekranu, zwraca zaô ona wskaúnik na strukturë "Screen", opisujâcâ otwarty ekran. Jeûeli ekran o podanej nazwie nie istnieje, to funkcja zwraca NULL. Jeûeli jako nazwë podamy NULL, to funkcja zwraca adres domyôlnego ekranu publicznego. Po uûyciu tej funkcji nie da sië danego ekranu zamknâê. Jeûeli adres ekranu nie jest nam juû potrzebny, naleûy uûyê funkcji: void UnlockPubScreen( UBYTE *name, struct Screen *screen ); Jako pierwszy parametr podaje sië zwykle NULL, a jako drugi wartoôê zwróconâ przez LockPubScreen(). Wywoîanie tej funkcji umoûliwia póúniej zamkniëcie danego ekranu przez program, który ekranem zarzâdza. Skoro znamy juû adres ekranu, na którym chcemy otworzyê okno, to naleûy teraz poinformowaê o tym funkcjë OpenWindowTagList(), która otworzy nam okno na tym wîaônie ekranie. Sîuûy do tego tag: WA_PubScreen -- jego parametrem jest po prostu adres ekranu (struktury "Screen"). Czas wiëc na maîy przykîadzik, utrwalajâcy zdobytâ wîaônie wiedzë: --------------------tu listing 6.---------------------------- Sâdzimy, ûe nie wymaga on dîuûszego komentarza: jeûeli poda sië przy uruchamianiu parametr w linii argumentowej, to program uzna ten parametr za nazwë ekranu publicznego i spróbuje otworzyê na nim okno. Bardziej eleganckie metody podawania parametrów omówimy w którejô z kolejnych czëôci. Poniewaû nie podaliômy przy otwieraniu okna tagów "WA_Left" oraz "WA_Width", to system otworzy okno maksymalnej wielkoôci, a wiëc o szerokoôci ekranu. Tagi "WA_Top" oraz "WA_Height" podaliômy po to, aby okno nie zasîaniaîo górnej listwy ekranu. Szerokoôê górnej listwy jest zapisana w strukturze "Screen" -- wynosi ona BarHeight+1. Nie moûna w to miejsce wstawiê jakiejô staîej wartoôci, gdyû szerokoôê listwy zaleûy od uûytej czcionki ekranowej. Istniejâ inne niû tag "WA_PubScreen" metody podawania, na którym ekranie ma byê otwarte okno: WA_PubScreenName -- parametrem jest wskaúnik na NAZWË ekranu publicznego, na którym chcemy otworzyê okno. WA_PubScreenFallBack -- uûyty w poîâczeniu z powyûszym powoduje, ûe jeûeli ekran o danej nazwie nie jest dostëpny, to okno zostanie otwarte na standardowym ekranie publicznym. WA_CustomScreen -- uûywany, gdy ekran, na którym chcemy otworzyê okno, nie jest ekranem publicznym (w praktyce oznacza to, ûe jesteômy wîaôcicielami tego ekranu -- sami go otworzyliômy). Parametrem tego tagu jest adres ekranu, tak samo jak w tagu "WA_PubScreen". No, teraz wypadaîoby samemu otworzyê ekran. Sîuûy do tego funkcja: struct Screen *OpenScreenTagList( struct NewScreen *newScreen, struct TagItem *tagList ); struct Screen *OpenScreenTags( struct NewScreen *newScreen, unsigned long tag1Type, ... ); Znaczenie parametrów jest analogiczne do omówionej w poprzedniej czëôci funkcji OpenWindowTagList() (tak samo, istnieje teû stara funkcja OpenScreen() -- bez tagów). Analogiczna jest równieû zwracana przez funkcjë wartoôê -- jest niâ wskaúnik na strukturë "Screen" (të samâ, co w "LockPubScreen()"), bâdú 0, gdy ekran nie moûe byê otwarty (bo np. nie wystarczyîo pamiëci). Tagów dla funkcji OpenScreenTagList() jest caîa masa, najwaûniejsze to: SA_Depth -- "gîëbokoôê" ekranu, tzn. liczba bitplanów. Gdyby ktoô nie wiedziaî: liczbë kolorów oblicza sië jako 2 do potëgi "liczba bitplanów". Standardowa wartoôê (tj. taka, jaka zostanie ustawiona, jeûeli ten tag w ogóle nie bëdzie podany) to 1 (2 kolory). SA_Title -- tytuî ekranu, wyôwietlany na listwie tytuîowej (NIE jest to równoznaczne z nazwâ ekranu publicznego). SA_Type -- typ ekranu -- PUBLICSCREEN, gdy ekran ma byê publiczny, CUSTOMSCREEN, gdy ma byê prywatny. SA_PubName -- nazwa ekranu publicznego (tag uûywany wtedy, gdy chcemy, aby ekran byî publiczny). SA_DisplayID -- rozdzielczoôê, w jakiej ma byê wyôwietlany ekran. Jako parametr podajemy staîe zdefiniowane w pliku "graphics/modeid.h" lub "graphics/displayinfo.h" (w zaleûnoôci od posiadanej wersji inkludów). Na przykîad, aby otrzymaê ekran o czëstotliwoôci odchylania PAL (50 Hz), w wysokiej rozdzielczoôci i z przeplotem, jako parametr podajemy: PAL_MONITOR_ID | HIRESLACE_KEY. SA_Pens -- ten wymaga dîuûszego komentarza. Jak wiadomo, ekrany mogâ mieê róûnâ liczbë kolorów, róûne mogâ teû byê poszczególne barwy. Barwy, zapisane jako skîadowe R (red -- czerwona), G (green -- zielona) i B (blue -- niebieska), sâ przyporzâdkowane numerom od 0 do "iloôê_kolorów-1". Zarówno system, jak i inne programy, chciaîby wiedzieê, którym z kolorów ma byê narysowana górna listwa ekranu, którym majâ byê rysowane lewe i górne krawëdzie gadûetów, a którym prawe i dolne (aby otrzymaê efekt trójwymiarowoôci), którym kolorem powinny byê rysowane normalne teksty, a którym teksty o szczególnym znaczeniu itp. To wszystko ustala wîaônie tag "SA_Pens". Jego parametrem jest adres do tablicy UWORDów, zawierajâcej informacje o numerach kolorów, przeznaczonych dla poszczególnych zadaï. Tablica ta powinna byê zakoïczona numerem ~0, czyli 0xFFFF. W pliku "intuition/screens.h" znajdujâ sië staîe, informujâce, w których elementach tablicy powinny byê numery kolorów dla odpowiednich celów, np. SHADOWPEN ustala, jakim kolorem majâ byê rysowane "ciemne krawëdzie" trójwymiarowych obiektów. Staîa ta ma wartoôê 4, co oznacza, ûe numer koloru sîuûâcego do tego celu ma byê odnotowany w czwartym elemencie tablicy (czyli w piâtym z kolei, bo pierwszy element tablicy ma w "C" indeks 0). W systemie 2.04 jest 9 takich "penów" (jak to przetîumaczyê?!), w 3.0 doszîy jeszcze 3, ustalajâce dokîadnie kolory na górnej listwie ekranu. Nie ma potrzeby podawaê caîej tablicy "penów". Moûna podaê np. tylko 3 pierwsze (a wiëc DETAILPEN, BLOCKPEN i TEXTPEN -- patrz "intuition/screens.h"), a zaraz po nich ~0, co spowoduje, ûe pozostaîe zostanâ ustawione na standardowe wartoôci. I tu nasz maîy apel. Jeûeli nie musicie, nie ustalajcie wîasnych, niestandardowych wartoôci. Najlepiej juû jako pierwszy element podaê ~0, co spowoduje, ûe wszystkie "peny" zostanâ ustawione na standardowe wartoôci. Ma to të zaletë, ûe Wasze programy nie bëdâ odstawaîy swym wyglâdem od reszty systemu. Jeûeli standardowe systemowe wartoôci ulegnâ zmianie (tak jak to miaîo miejsce w wypadku kolorów górnej listwy ekranu pomiëdzy OS 2.04 i OS 3.0), to przy takim rozwiâzaniu Wasz program dostosuje sië do tego -- uûytkownicy bëdâ Wam wdziëczni. Jeûeli zaleûy Wam na innych wartoôciach, to powinniôcie mimo wszystko daê uûytkownikowi moûliwoôê ich zmiany (takâ opcjë ma np. edytor GoldEd, a takûe sam AmigaOS od wersji 3.0 -- program Palette), bo uûytkownik moûe chcieê inaczej, i ma do tego prawo! Jednym sîowem, nic na siîë! Otwarty za pomocâ OpenScreenTagList() z uûyciem powyûszych tagów ekran bëdzie miaî standardowe rozmiary oraz pozycjë. I tu ponawiamy nasz apel. Nie zmieniajcie tego bez waûnego powodu! Standardowe wartoôci ustawia sam uûytkownik, za pomocâ systemowego programu Overscan, i jest naprawdë denerwujâce, gdy program otwiera ekran 640 x 256, mimo ûe w Overscan jest ustawione 724 x 283... Jeûeli jednak musicie mieê inny rozmiar, to uûywa sië do tego tagów "SA_Width" oraz "SA_Height", których znaczenie jest chyba oczywiste (szerokoôê, wysokoôê). Istniejâ teû tagi "SA_Left" i "SA_Top", ustalajâce poczâtkowâ pozycjë ekranu w stosunku do lewego górnego rogu, ustalonego przez uûytkownika w programie Overscan (standardowo 0, 0). To samo dotyczy wîaôciwie równieû rozdzielczoôci oraz liczby kolorów: o tym wszystkim powinien móc decydowaê uûytkownik. Najbardziej eleganckim rozwiâzaniem jest uûycie ScreenMode-requestera, w którym uûytkownik moûe sobie podstawowe atrybuty dowolnie ustaliê. Zostanie to pokazane w którejô z kolejnych czëôci. Ekran ma po otwarciu ustawienie kolorów takie samo, jak ekran Workbencha. "Ôwieûo otwarty" ekran publiczny nie jest w gruncie rzeczy publiczny, tzn. jest otwierany w trybie prywatnym. Jest to doôê sensowne, bo program otwierajâcy ekran publiczny moûe chcieê najpierw dokonaê jakichô inicjalizacji -- nasz prymitywny przykîad, rzecz jasna, nic takiego nie bëdzie robiî. Gdy program chce zezwoliê innym na otwieranie na swym ekranie publicznym okien, musi zmieniê status tego ekranu, wywoîujâc funkcjë: UWORD PubScreenStatus( struct Screen *screen, unsigned long statusFlags ); Pierwszym parametrem jest, oczywiôcie, ekran, drugim -- status, jaki ma otrzymaê ekran. Na razie istnieje tylko jedna flaga statusu: PSNF_PRIVATE. Podaje sië jâ, gdy chce sië ekran uczyniê na powrót prywatnym. Jeûeli chce sië, tak jak my, uczyniê ekran publicznym, to podaje sië 0. Funkcja zwraca poprzedni status ekranu. W wypadku, gdy chcemy za pomocâ tej funkcji uczyniê ekran publiczny na powrót prywatnym, funkcja moûe zwróciê 0, aby zasygnalizowaê niepowodzenie (spowodowane np. tym, ûe na ekranie sâ otwarte okna innych programów). Gdy chcemy zamknâê nasz ekran, naleûy uûyê funkcji: BOOL CloseScreen( struct Screen *screen ); Parametrem jest ekran, który ma zostaê zamkniëty. Funkcja zwraca 0, jeûeli nie udaîo sië zamknâê ekranu. Dzieje sië to wtedy, gdy na ekranie sâ otwarte jakieô okna (albo uûyty zostaî LockPubScreen() bez dopeîniajâcego go UnlockPubScreen()). Wykorzystamy të wîasnoôê w naszym przykîadzie. W przykîadzie uûyjemy jeszcze jednej funkcji systemu operacyjnego: LONG ModeNotAvailable( unsigned long modeID ); UWAGA! Funkcja ta znajduje sië w bibliotece "graphics.library", a NIE w Intuition, naleûy wiëc të bibliotekë najpierw otworzyê. Funkcja sîuûy do sprawdzania, czy podany jej jako parametr identyfikator trybu wyôwietlania (liczba, którâ podaje sië jako parametr tagu "SA_DisplayID") jest poprawnym, dostëpnym na danym komputerze trybem. Zwraca ona 0, jeûeli tryb moûe byê uûyty; w przeciwnym wypadku zwraca jednâ z wartoôci zdefiniowanych w pliku "graphics/displayinfo.h" (np. DI_AVAIL_NOCHIPS oznacza, ûe nie masz odpowiednich koôci graficznych, niezbëdnych do wyôwietlenia danego trybu, moûe to spotkaê na przykîad posiadaczy Amig 3000 z OS 3.x, chcâcych otworzyê ekran w trybie HAM8). Tyle teorii w tym odcinku. W nastëpnym zamieszczë przykîady. Tych z Was, którzy sâ niecierpliwi i juû nie mogâ sië doczekaê na przykîady, zwiâzane z tym odcinkiem kursu, informujë, ûe moûna je uzyskaê, jeûeli ma sië dostëp do Internetu. Do mojej strony WWW moûna sië dostaê, zaglâdajâc pod: http://www.uci.agh.edu.pl/student/infgrp/iskra/public_html/index.html, a listy do mnie proszë kierowaê pod adresem: iskra@student.uci.agh.edu.pl.