14-ôciE Mam bardzo smutnâ wiadomoôê. To juû przedostatni odcinek kursu E. Rafaî Wiosna Mimo smutnej okazji, niech tradycji stanie sië zadoôê. Wszystkim mëûczynom (lub menszczyznom, jak to sîychaê w reklamie Gilette) o mocnych nerwach polecam film "Crimson Tide" ("Karmazynowy przypîyw"). Naprawdë jest znakomity i trzyma w napiëciu od 5. minuty od rozpoczëcia do 5. minuty przed koïcem. Wracajmy jednak do E. W tym odcinku zakoïczë opisywanie komunikatów IDCMP, które moûe otrzymaê okno aplikacji. Opis otwierania ekranów znajdziecie w kursie C, a uûywania gadûetów znajduje sië w publikowanym niedawno materiale o gadtools.library. Sprawë GUI i jego obsîugi moûna uwaûaê za zamkniëtâ. Ochîapy Przypominam -- to, co opisuje poniûej naleûy wpisaê jako piâty argument funkcji OpenW(), która jest funkcjâ wewnëtrznâ E lub jako argument tagu WA_IDCMP przy otwieraniu okna systemowâ funkcjâ OpenWindowTagList(). Argumenty te majâ wartoôci binarne, wiëc moûna je bardzo îatwo îâczyê przez dodawanie. IDCMP_INTUITICKS -- niekiedy bardzo uûyteczna wiadomoôê. Nie pociâga za sobâ ûadnych argumentów, natomiast przysyîana jest mniej wiëcej 10 razy na sekundë. Podkreôlam sîowo "mniej wiëcej", gdyû nie jest to np. przerwanie generowane przez ukîad CIA z dokîadnoôciâ do milisekund... Intuiticks sâ przydatne, gdy chcesz coô sprawdzaê albo odôwieûaê w odstëpach czasowych w miarë staîych. Jeûeli Intuition nie otrzyma odpowiedzi na wysîany komunikat typu IDCMP_INTUITICKS (tzn. nie odpowiesz na niego funkcjâ ReplyMsg()), wysyîanie dalszych zostanie wstrzymane. IDCMP_DELTAMOVE -- wiadomoôê podobna do IDCMP_MOUSEMOVE, z tym ûe system zwraca nie obrobione wartoôci, ôwiadczâce o relatywnym ruchu myszy. Moûna stosowaê razem z IDCMP_MOUSEMOVE. Wtedy w odpowiednich polach IntuiMessage bedâ przekazywane relatywne wartoôci ruchu myszy, a nie poîoûenie kursora wzglëdem lewego górnego rogu okna. Naleûy pamiëtaê, aby okno miaîo ustawionâ flagë WFLG_REPORTMOUSE. Oto przykîad uûycia MOUSEMOVE i DELTAMOVE: ^- -> -> Program ilustrujâcy sposób interpretacji danych -> przekazywanych przez wiadomoôci typu -> IDCMP_MOUSEMOVE i IDCMP_DELTAMOVE -> -> ************ (c) RW & Magazyn AMIGA 1995 ************ ENUM KONIEC,BLAD_OKNO MODULE 'intuition/intuition','intuition/intuitionbase' MODULE 'intuition/screens','graphics/text' DEF wnd:PTR TO window,klasa,kod,msx,msy PROC main() HANDLE otworzGUI() Colour(1,0) REPEAT zdarzenie() TextF(30,35,'msg.class: \z\h[8] msg.code: \h[4]',klasa,kod) TextF(30,45,'msg.mousex \d[4] msg.mousey \d[4]',msx,msy) UNTIL klasa=IDCMP_CLOSEWINDOW EXCEPT DO zamknijGUI() IF exception THEN WriteF('Nie mogë \s!\n', ListItem(['','otworzyê okna'],exception)) ENDPROC PROC otworzGUI() /* Poniûszy fragment zawiîego kodu pozwala na okreôlenie wysokoôci i szerokoôci domyôlnej czcionki ekranowej. Problem w tym, ûe funkcja TextF() wyôwietla teksty uûywajâc domyôlnej czcionki SYSTEMOWEJ, a nie EKRANOWEJ... Ambitnym Czytelnikom pozostawiam zmianë sposoby wyôwietlania danych tak, aby byîo ono realizowane za pomocâ systemowej funkcji PrintIText(). */ DEF ourscreen:PTR TO screen, ourdrawinfo:PTR TO drawinfo DEF txtfont:PTR TO textfont, ibase:PTR TO intuitionbase DEF deffontwidth, deffontheight, ibaselock ibaselock:=LockIBase(NIL) ibase:=intuitionbase ourscreen:=ibase.activescreen ourdrawinfo:=GetScreenDrawInfo(ourscreen) txtfont:=ourdrawinfo.font deffontwidth:=txtfont.xsize deffontheight:=txtfont.ysize FreeScreenDrawInfo(ourscreen,ourdrawinfo) UnlockIBase(ibaselock) IF (wnd:=OpenW(10,15,60*deffontwidth,10*deffontheight, IDCMP_CLOSEWINDOW+IDCMP_MOUSEMOVE -> +IDCMP_DELTAMOVE -> spróbuj usunâê tâ linië ,WFLG_DRAGBAR+WFLG_DEPTHGADGET+ WFLG_CLOSEGADGET+WFLG_ACTIVATE+ WFLG_REPORTMOUSE, 'Ruchy myszki jak na dîoni', NIL,1,NIL))=NIL THEN Raise(BLAD_OKNO) ENDPROC PROC zamknijGUI() IF wnd THEN CloseWindow(wnd) ENDPROC PROC zdarzenie() DEF mes:PTR TO intuimessage REPEAT klasa:=0 IF mes:=GetMsg(wnd.userport) klasa:=mes.class kod:=mes.code msx:=mes.mousex msy:=mes.mousey ReplyMsg(mes) ELSE WaitPort(wnd.userport) ENDIF UNTIL klasa ENDPROC IDCMP_NEWPREFS -- takâ wiadomoôê otrzymuje aplikacja, gdy zmieniâ sië preferencje systemu. IDCMP_ACTIVEWINDOW i IDCMP_INACTIVEWINDOW -- dwa typy wiadomoôci, informujâce aplikacjë, ûe jej okno zostaîo zaktywizowane (uûytkownik kliknâî myszâ wewnâtrz obszaru okna) lub zdeaktywizowane (uûytkownik kliknâî myszâ poza obszarem okna). Nie myliê z WFLG_WINDOWACTIVE, flagâ okna, nie typem wiadomoôci!!! IDCMP_DISKINSERTED i IDCMP_DISKREMOVED -- wiadomoôci przekazywane aplikacji w chwili wîoûenia dyskietki do dowolnej stacji dysków lub wyjëcia jej. Informacja nie musi dotyczyê wyîâcznie dyskietek -- moûe to byê równie dobrze jakieô urzâdzenie traktowane przez system jako tzw. removable media. IDCMP_IDCMPUPDATE -- wiadomoôê sîuûâca do komunikacji z gadûetami boopsi. Wyûsza szkoîa jazdy. IDCMP_CHANGEWINDOW -- wiadomoôê wysyîana aplikacji w chwili zmiany wymiarów lub poîoûenia okna. Moûe to zrobiê uûytkownik lub sam program, uûywajâc funkcji SizeWindow(), MoveWindow(), ChangeWindowBox() lub ZipWindow(). IDCMP_MENUHELP -- bardzo ciekawy typ wiadomoôci. Otrzyma jâ aplikacja wtedy, gdy uûytkownik naciônie klawisz [Help] podczas wybierania jakiejô opcji z menu. MENUHELP dziaîa nawet wtedy, gdy opcja jest niedostëpna (ghosted). Wiadomoôci tego typu bëdâ wysyîane tylko wtedy, gdy w tagach, przekazywanych funkcji OpenWindowTagList() znajduje sië tag WA_MenuHelp. (Nie ma odpowiednika tego taga wôród flag typu WFLG_!) Programista moûe odczytaê, który element menu zostaî "wybrany" w polu code. Jeûeli ûadna opcja nie znajdowaîa sië pod kursorem myszy, w chwili gdy uûytkownik naciskaî [Help], wartoôê pola code bëdzie wynosiîa MENUNULL. IDCMP_GADGETHELP -- (nowoôê w systemie V39, czyli 3.0) wiadomoôê wysyîana wtedy, gdy kursor myszy znajduje sië nad gadûetami. Aby z tego skorzystaê, naleûy uûyê funkcji HelpControl() w celu wîâczenia moûliwoôci otrzymywania wiadomoôci typu IDCMP_GADGETHELP. W jej polu code jest numer gadûetu, nad którym znajduje sië kursor myszy. To mniej wiëcej wszystkie typy wiadomoôci, które moûe otrzymaê aplikacja. Zajmijmy sië teraz flagami, którymi okreôla sië parametry i stan nowo otwieranego okna. WFLG_ WFLG_SIZEGADGET -- decyduje o obecnoôci gadûetu, umoûliwiajâcego zmianë rozmiaru okna. WFLG_DRAGBAR -- okno bëdzie miaîo listwë, umoûliwiajâcâ jego przesuwanie. Jeûeli nie uûyjesz tej flagi, okna nie bëdzie moûna przesunâê. WFLG_DEPTHGADGET -- gadûet umoûliwiajâcy ustawianie okna wzglëdem innych. WFLG_CLOSEGADGET -- gadûet umoûliwiajâcy zamkniëcie okna. Jeûeli nie uûyjesz tej flagi, Twojego okna nie bëdzie moûna zamknâê (aplikacja nie otrzyma wiadomoôci IDCMP_CLOSEWINDOW nawet, gdy zaûâdasz, aby jâ przysyîano!). WFLG_SIZEBRIGHT -- okno bëdzie miaîo dodatkowâ listwë po prawej stronie (np. na suwaki). WFLG_SIZEBBOTTOM -- okno bëdzie miaîo dodatkowâ listwë u doîu (np. na suwaki). WFLG_SMART_REFRESH -- flaga dotyczâca odtwarzania zawartoôci okna, kiedy zmieniâ sië jego parametry, np. wielkoôê. Tym razem zadba o to system. WFLG_SIMPLE_REFRESH -- j.w., ale o odtwarzanie zawartoôci okna dba aplikacja. WFLG_SUPER_BITMAP -- j.w., w tym wypadku sysytem magazynuje zawartoôê okna (która moûe byê wiëksza niû samo okno) w specjalnym buforze, dziëki czemu odôwieûanie zawartoôci (tak jak w wypadku WFLG_SMART_REFRESH i WFLG_SIMPLE_REFRESH) jest wîaôciwie niepotrzebne. Wiëcej o odôwieûaniu okien napisaîem w 12. odcinku cyklu. WFLG_BACKDROP -- okreôla specjalny typ okna. Jest ono otwierane pod wszystkimi innymi "normalnymi" oknami, ale nad innymi oknami backdrop. Zwykle ten typ okna okreôla sië jeszcze flagâ WLFG_BORDERLESS (o tym za chwilë), dziëki temu okno jest niewidoczne na ekranie. Tym sposobem uzyskuje sië zîudzenie dziaîania pustego ekranu tak jak okna -- wszak ekrany nie otrzymujâ wiadomoôci IDCMP... Okno o tych samych rozmiarach co ekran, bez nazwy i otworzone z flagami WFLG_BORDERLESS+WFLG_BACKDROP pozwala na zrealizowanie podobnych rozwiâzaï interfejsu uûytkownika, jak np. w PowerPackerze czy programach malarskich. Jedynym gadûetem systemowym w tej sytuacji, którego moûna uûyê, jest gadûet zamkniëcia okna (gadûet zmiany wielkoôci jest bez sensu, a zmiany gîëbokoôci zasîoni jego odpowiednik na ekranie). WFLG_REPORTMOUSE -- aplikacja bëdzie otrzymywaîa wiadomoôci typu IDCMP_MOUSEMOVE i/lub IDCMP_DELTAMOVE. WFLG_GIMMEZEROZERO -- okreôla poîoûenie poczâtku koordynat okna. W normalnej sytuacji znajduje sië on w lewym górnym rogu ramki okna. Uûywajâc GZZ moûna go umieôciê w lewym górnym rogu wewnëtrznego obszaru okna. Poczâtkujâcy programiôci robiâ bîad, nie uûywajâc tej techniki do lokalizacji gadûetów, tekstów i innych elementów graficznych. Gdy uûytkownik zmieni wielkoôci domyôlnych czcionek, czësto sië zdarza, ûe napis "wychodzi" na ramkë. (Przy okazji: poîoûenia kursora myszy, zwracane przez wiadomoôci typu IDCMP_MOUSEMOVE, sâ zawsze relatywne do ramki okna, niezaleûnie od tego, czy uûyto flagi WFLG_GIMMEZEROZERO. W strukturze otwartego okna znajdujâ sië dwa pola --- gzzmousex i gzzmousey, które podajâ poîoûenie kursora w stosunku do rogu obszaru roboczego.) WFLG_BORDERLESS -- okno nie bëdzie miaîo obwódki. Jeûeli chcesz, ûeby okno nie byîo w ogóle widoczne, nie moûesz uûyê flagi WFLG_DRAGBAR oraz flag umieszczajâcych w jego ramce gadûety. Pamiëtaj teû, aby tytuî okna byî pusty. WFLG_ACTIVATE -- okno po otworzeniu bëdzie aktywne (normalnie -- nie zostanie uaktywnione). WFLG_RMBTRAP -- po wciôniëciu prawego przycisku myszy menu nie zostanie pokazane. Aplikacja powinna sama zadbaê o to, aby dostëp do menu zostaî zapewniony (np. Deluxe Paint). WFLG_NOCAREREFRESH -- programistë nie obchodzi odôwieûanie okna (aplikacja nie otrzyma wiadomoôci IDCMP_REFRESHWINDOW). Istniejâ jeszcze inne flagi, ale przeznaczone sâ one dla zaawansowanych programistów. * To juû koniec. Dajë Wam miesiâc na przygotowanie sië do ostatniego odcinka kursu. W nastëpnym numerze opiszë teû ôwieûutkâ, nowâ, wersjë E -- 3.2a.