Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Wykład 3a Działanie aplikacji okienkowej

Podobne prezentacje


Prezentacja na temat: "Wykład 3a Działanie aplikacji okienkowej"— Zapis prezentacji:

1 Wykład 3a Działanie aplikacji okienkowej
Systemy operacyjne Wykład 3a Działanie aplikacji okienkowej dr inż. Wojciech Bieniecki Instytut Nauk Ekonomicznych i Informatyki

2 Zdarzeniowy model aplikacji
System Windows bazuję na komunikatach, które zarządzają stanem aplikacji. Komunikaty informują aplikacje o tym co się dzieje w systemie. - komunikaty poleceń (ang. command messages) - wysyłane w celu wykonania jakiejś czynności komunikaty powiadomień (ang. notification messages) - dla powiadomienia aplikacji lub systemu o wystąpieniu zdarzenia. Komunikaty przetwarzane są w kolejce 1. wystąpienie zdarzenia - system umieszcza je w kolejce komunikatów, 2. process pobiera komunikat z kolejki 3. komunikat jest wysyłany pod adresem okna docelowego, 4. jeżeli w procedurze okna, uwzględniono jego obsługę, jest ona wywoływana, w przeciwnym wypadku obsługa w sposób domyślny

3 Zdarzeniowy model aplikacji
Działanie aplikacji Windows polega na przetwarzaniu nieskończonej pętli while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; }

4 Budowa komunikatu HWND hwnd – wskaźnik na okno, do którego adresowany jest komunikat UINT message – określa identyfikator komunikatu (standardowy lub własny) WPARAM wParam, LPARAM lParam – dodatkowe parametry komunikatu. Razem 8 bajtów. Możliwość wykorzystania tylko kilku pierwszych bajtów (parametr wyższy). DWORD time Czas w momencie, którym zdarzenie miało miejsce. Pole mało istotne, rzadko używane. POINT pt; Pole przechowuje współrzędne kursora w momencie zaistnienia zdarzenia. To pole także rzadko jest używane.

5 Komunikaty okna: Komunikaty niekolejkowane
WM_CREATE - Procedura obsługi okna otrzymuje ten komunikat podczas wykonywania przez system operacyjny funkcji CreateWindow. WM_DESTROY - Komunikat informujący o tym, że system rozpoczął proces niszczenia okna na żądanie użytkownika. Komunikaty kolejkowane WM_PAINT - Większość programów pracujących pod kontrolą systemu Windows wywołuje funkcję UpdateWindow podczas inicjalizacji w funkcji WinMain zaraz przed uruchomieniem pętli komunikatów. W ten sposób system wysyła do procedury okna pierwszy komunikat WM_PAINT, który informuje procedurę okna o konieczności wypełnienia obszaru klienta. Następnie procedura okna otrzymuje komunikat WM_PAINT zawsze wtedy, gdy ma miejsce jedno z następujących zdarzeń: - wcześniej zasłonięty obszar okna jest odsłaniany w wyniku zmiany pozycji innego okna przez użytkownika; - użytkownik zmienia rozmiar okna (jeżeli styl klasy okna posiada flagi CS_HREDRAW i CS_VREDRAW); - program wykorzystuje funkcje ScrollWindow lub ScrollDC do przewinięcia części jego obszaru klienckiego; - program używa funkcji InvalidateRect lub InvalidateRgn do jawnego wygenerowania komunikatu WM_PAINT.

6 WM_KEYDOWN - Komunikaty wysyłane do okna podczas wciskania lub zwalniania
WM_KEYUP niesystemowego przycisku klawiatury. Parametry: - wParam określa kod jego wirtualnego przycisku. WM_COMMAND - Komunikat wysyłany gdy użytkownik wybiera polecenie menu lub gdy kontrolka wysyła komunikat do okna nadrzędnego. Parametry: - wParam (high-word) ma wartość 0 dla poleceń menu, a w przypadku kontrolki, specyficzny dla niej kod powiadomienia; - wParam (low-word) określa identyfikator pola menu lub kontrolki; - lParam ma wartość 0 dla poleceń menu lub określa uchwyt okna kontrolki. WM_LBUTTONDOWN - Komunikaty wysyłane gdy użytkownik wciska (zwalnia) lewy (prawy) przycisk WM_LBUTTONUP myszy podczas, gdy kursor znajduje się w obszarze klienckim okna. Parametry: WM_RBUTTONDOWN - wParam określa jakie wirtualne przyciski są wciśnięte: WM_RBUTTONUP • MK_CONTROL – przycisk CTRL, • MK_LBUTTON – lewy przycisk myszy, • MK_MBUTTON – środkowy przycisk myszy, • MK_RBUTTON – prawy przycisk myszy, • MK_SHIFT – przycisk SHIFT; - lParam (low-word) określa współrzędną x kursora; - lParam (high-word) określa współrzędną y kursora. WM_MOUSEMOVE - Komunikat wysyłany do okna podczas ruchu kursora. Parametry komunikatu są identyczne jak w przypadku wciskania i zwalniania przycisków myszy.

7 Programowanie zdarzeniowe
Ideą programowania zdarzeniowego jest to, że zaimplementowane przez nas funkcje nie są wywoływane jawnie w kodzie programu, lecz przez system operacyjny lub wydzielony moduł programu. Funkcje te nazywa się zwrotnymi (callback). Jest to nawiązanie do idei przerwań Komunikaty: Funkcje obsługujące tzw. kolejkę komunikatów pochodzących od systemu lub: • mysz; • klawiatura; • zmiana w interfejsie graficznym programu; • zegar; • operacje plikowe lub sieciowe. Wyjątki: Funkcje obsługujące błędy czasu wykonywania mogące wystąpić w programie: • operacje arytmetyczne (np. dzielenie przez zero); • operacje wejścia / wyjścia (brak pliku, brak połączenia sieciowego); • błędy adresowania pamięci (przekroczenie zakresu tablicy, nieistniejący obiekt).

8 Budowa aplikacji Windows
Aplikacja Windows działa w następujących fazach: Tworzymy tzw klasę okna, definiujemy jego wygląd wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } Tworzymy w pamięci instancję okna hwnd = CreateWindow (szAppName, TEXT ("The Hello Program"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ;

9 Budowa aplikacji Windows
Uruchamiamy nieskończoną pętlę przetwarzania komunikatów while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } Funkcja DispatchMessage uruchamia tzw funkcję okna, w której możemy obsłużyć komunikaty LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) case WM_LBUTTONDOWN : MessageBox(hwnd, “Zostal wcisniety lewy przycisk myszy…", „Informacja", MB_ICONINFORMATION | MB_OK); return 0; case WM_CLOSE: if (IDCANCEL == MessageBox(hwnd, „Czy chcesz zamknac program?", „Pytanie", MB_ICONQUESTION | MB_OKCANCEL)) return 0; else break; case WM_DESTROY : PostQuitMessage(0); } return DefWindowProc (hwnd, message, wParam, lParam); Komunikaty obsłużone przez użytkownika nie powinny trafić do domyślnej procedury okna ‘DefWindowProc’. W tym celu po obsłużeniu komunikatu należy wyjść z procedury zwracając wartość zero. Wszystkie komunikaty, których nie obsłużył użytkownik, trafiają do domyślnej procedury okna ‘DefWindowProc’.

10 Reakcja systemu na zdarzenie
Program WINAPI Funkcja WinMain Definiowanie klas okien programu Rejestracja zdefiniowanych klas Utworzenie okna głównego Wyświetlenie okna głównego Pętla komunikatów KONIEC Reakcja systemu na zdarzenie Pobranie komunikatu Przekazanie komunikatu Procedura obsługi okna 1 System operacyjny Kolejka komunikatów Obsługa komunikatów okna 1 HWND WM_CLOSE 0 0 HWND WM_DESTROY 0 0 Procedura obsługi okna 2 Obsługa komunikatów okna 2 HWND WM_COMMAND LPARAM WPARAM HWND WM_QUIT 0 0

11 Implementacja (Visual C++, MFC)
Architektura Dokument-Widok Podstawowe klasy CApplication – klasa aplikacji, uruchamiająca aplikację CMainFrame – klasa okna głównego CDocument – klasa dokumentu – obiekt skojarzony z otwartym plikiem CView – klasa widoku. Obiekt skojarzony z oknem wyświetlającym dokument. Wizualnie – tzw obszar klienta okna – część wewnątrz ramki Implementacja pętli komunikatów BEGIN_MESSAGE_MAP(CImgViewerView, CScrollView) //{{AFX_MSG_MAP(CImgViewerView) ON_WM_ERASEBKGND() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview) END_MESSAGE_MAP()

12 Implementacja Java W Javie i C# zaimplementowano Delegacyjny model obsługi zdarzeń W Javie wprowadzono tu koncepcję "oddelegowania" obsługi: metoda, która obsługuje zdarzenie jest metodą innej klasy niż obiekt, któremu zdarzenie się przytrafiło. Słuchacz (ang. Listener) to obiekt, który może obsługiwać zdarzenia. Aby móc generować obiekty-Słuchacze, klasa musi implementować interfejs nasłuchu. Interfejs nasłuchu zawiera abstrakcyjne metody do obsługi zdarzeń. Jego implementacja oznacza, iż metody te zyskują konkretne definicje. Java dostarcza wiele standardowych interfejsów nasłuchu, przygotowanych do odbioru konkretnych rodzajów zdarzeń. Klasy-słuchacze mogą implementować jeden lub kilka z tych interfejsów, zyskując w ten sposób zdolność do obsługi wybranych zestawów rodzajów zdarzeń.

13 Przykład - nasłuch przycisku
import javax.swing.*; import java.awt.*; import java.awt.event.*; // by obsługiwać zdarzenia class Przycisk extends JFrame implements ActionListener { JButton b1 = new JButton("Przycisk 1"); JButton b2 = new JButton("Przycisk 2"); JTextField t = new JTextField(20); Przycisk(){ setLayout(new GridLayout(3,1)); b1.addActionListener(this); b2.addActionListener(this); getContentPane().add(t); getContentPane().add(b1); getContentPane().add(b2); pack(); setVisible(true); } public void actionPerformed(ActionEvent e){ t.setText(e.getActionCommand()); public static void main(String[] args){ new Przycisk();

14 Zdarzenie „akcja” tworzy obiekt ActionEvent
Działanie nasłuchu Zdarzenie „akcja” tworzy obiekt ActionEvent Interfejs nasłuchu ActionListener zawiera deklarację void actionPerformed(ActionEvent e); implementacja [ ŻRÓDŁO] Przycisk (JButton b) Klasa słuchacza: class Przyciski implements ActionListener { public void actionPerformed(ActionEvent e) System.out.println("Wciśnięto przycisk"); } CALL Przyłączenie b.addActionListener(p) KLIK Obiekt słuchacza akcji (może być również kontenerem przycisku) Przyciski p = new Przyciski();

15 Uwagi 1. Każdy obiekt Javy może być Słuchaczem, jeśli tylko jego klasa implementuje jakiś zestaw interfejsów nasłuchu 2. Zdarzenia dla danego Źródła są generowane tylko wtedy, gdy do źródła przyłączony jest Słuchacz 3. Metody obsługi zdarzeń (tu: actionPerformed) nie zwracają żadnych wyników. 4. Ze względu na strukturyzację zdarzeń i interfejsów nasłuchu kod jest odporny na błędy: np. metoda actionPerformed musi mieć jako argument zdarzenie klasy ActionEvent 5. Do badania właściwości zdarzenia stosuje się wyłącznie metody (w klasach zdarzeń nic ma publicznych pól). Przykładem może być getActionCommand(), która zwraca napis skojarzony ze zdarzeniem ACTION_PERFORMED (tu – napis na przycisku). 6. Zdarzenia są filtrowane na niskim, ukrytym poziomie. Upraszcza to pisanie kodu.

16 Zdarzenia fizyczne i semantyczne
java.util.EventObject +-- java.awt.AWTEvent +-- ActionEvent +-- AdjustmentEvent +-- ItemEvent +-- TextEvent +-- ComponentEvent +-- ContainerEvent +-- FocusEvent +-- InputEvent | KeyEvent | MouseEvent +-- WindowEvent ComponentEvent -> zdarzenia fizyczne (np. kliknięcie myszą czy zmiana rozmiaru komponentu). Wszystkie te zdarzenia dotyczą komponentów (stąd uszczegółowiony sposób identyfikacji źródła - metoda getComponent() z klasy ComponentEvent zwracająca referencję do obiektu klasy Component). Zdarzenie semantyczne, mające znaczenie zależne od kontekstu: ActionEvent - akcja ItemEvent - zmiana stanu elementu wybieralnego AdjustmentEvent - dostosowanie obiektu dostosowywalnego TextEvent - zmiana tekstu obiektu tekstowego

17 Interfejsy nasłuchu zdarzeń
Klasa zdarzenia Zdarzenie – stałej identyfikującej zdarzenie Nazwa metody obsługi danego zdarzenia void metoda(Klasa_zdarzenia k) Nasłuch ActionEvent ACTION_PERFORMED actionPerformed ActionListener AdjustmentEvent ADJUSTMENT_VALUE_CHANGED adjustmentValueChanged AdjustmentListener ItemEvent ITEM_STATE_CHANGED itemStateChanged ItemListener TextEvent TEXT_VALUE_CHANGED textValueChanged TexlListener MouseEvent MOUSE_ENTERED MOUSE_EXITED MOUSE_PRESSED MOUSE_RELEASED MOUSE_CLICKED mouseEntered mouseExited mousePressed mouseReleased mouseClicked MouseListener MouseMotionEvent MOUSE_MOVED MOUSE_DRAGGED mouseMoved mouseDragged MouseMotionListener KeyEvent KEY_PRESSED KEY_RELEASED KEY_TYPED keyPressed keyReleased keyTyped KeyListener

18 Interfejsy nasłuchu zdarzeń
Klasa zdarzenia Zdarzenie Metody obsługi Nasłuch KeyEvent KEY_PRESSED KEY_RELEASED KEY_TYPED keyPressed keyReleased keyTyped KeyListener FocusEvent FOCUS_GAINED FOCUS_LOST focusGained focusLosed FocusListener ContainerEvent COMPONENT_ADDED COMPONENT_REMOVED componentAdded componentRemoved ContainerListener ComponentEvent COMPONENT_HIDDEN COMPONENT_SHOWN COMPONENT_MOVED COMPONENT_RESIZED componentHidden componentShown componentMoved componentResized ComponentListener WindowEvent WINUOW_ACTIVATED WINDOW_DEACTIVATED WINDOW_ICONIFIED WINDOW_DEICONIFIED WINDOW_OPENED WINDOW_CLOSING WINDOW_CLOSED windowActivated windowDeactivated windowIconified windowDeiconified windowOpened windowClosing windowClosed WindowListener

19 Implementacja Python PyQt – sygnały i sloty
Charakterystyczną cechą Qt jest mechanizm sygnałów i slotów będący sposobem porozumiewania się elementów aplikacji. Sygnał emitowany jest w przypadku wystąpienia określonej akcji (np. przyciśnięto przycisk). Slot to funkcja połączona (za pomocą QtCore.QObject.connect()) z określonym sygnałem i jest wykonywana, gdy taki sygnał zostanie wyemitowany. Połączenia sygnałów i slotów: - sygnał może być połączony z wieloma slotami - sygnał może być połączony z innym sygnałem - slot może być połączony z wieloma sygnałami - w PyQt sygnały są emitowane przez metodę QtCore.QObject.emit() - połączenia mogą być bezpośrednie - synchroniczne lub kolejkowane - asynchroniczne - można tworzyć połączenia między wątkami - sygnały są rozłączane za pomocą metody QtCore.QObject.disconnect()

20 Implementacja JavaScript
Rejestrowanie zdarzenia inline polega na określeniu zdarzenia wewnątrz znacznika. <a href="strona.html" onclick="alert(' Kliknąłeś! ')">kliknij</a> Rejestrowanie zdarzenia w sekcji skryptu (tu: z zastosowaniem funkcji anonimowej document.getElementById('Przycisk').onclick = function() { alert('zostałem klikniety!'); } Rejestrowanie zdarzenia z użyciem addEventListener var element = document.getElementById('Przycisk'); element.addEventListener('click', startDragDrop, false); element.addEventListener('click', wypiszCos, false); element.addEventListener('click', function() {this.style.color = 'red'; }, false);

21 JavaScript – Kaskadowe wykonywanie zdarzeń
Załóżmy istnienie zagnieżdżonych bloków <div style="..." id="blok1">1     <div style="..." id="blok2">2             <div style="..." id="blok3">3</div>     </div> </div> <script type="text/javascript"> document.getElementById('blok1').onclick = function() { alert('Kliknąłeś mnie!')}; </script> Kliknięcie w element wewnętrzny powoduje po wykonaniu zdarzenia przesłanie go do elementu otaczającego (tu zawsze wywoła się alert) Wyłączenie tego zjawiska realizujemy poprzez funkcję stopPropagation function stopBubble(e) {   if (!e) var e = window.event;   e.cancelBubble = true;   if (e.stopPropagation) e.stopPropagation(); } document.getElementById('blok31').onclick = function() {  alert('Kliknąłeś mnie!')} document.getElementById('blok32').onclick = function(e){ stopBubble(e);} document.getElementById('blok33').onclick =

22 Architektura MVC Architektura MVC jest jedną z implementacji delegacyjnego modelu obsługi zdarzeń. Zakłada podział składników systemu aplikacyjnego na trzy kategorie: –Model (komponenty modelu): komponenty reprezentujące dane, na których operują aplikacje; komponenty modelu oferują także metody dostępu do danych –View (komponenty prezentacji): komponenty reprezentujące wizualizację (prezentację) danych dla użytkownika; komponenty prezentacji pobierają dane od komponentów modelu, a następnie wyświetlają je na ekranie użytkownika –Controller (komponenty sterujące): komponenty przechwytujące żądania użytkowników i odwzorowujące je w wywołania metod komponentów modelu; następnie komponenty sterujące przekazują sterowanie do komponentów prezentacji

23 Implementacja JavaServlet
Przeglądarka WWW wysyła sparametryzowane żądanie uruchomienia serwletu Controller (1). Po wywołaniu, serwlet Controller analizuje żądanie i tworzy obiekty wymagane do dalszego przetwarzania żądania – m.in. obiekty klas zewnętrznych JavaBeans realizujących funkcję Model. W obiektach tych wywoływane są funkcje logiki biznesowej (2). Następnie, serwlet Controller przekazuje żądanie do odpowiedniej strony Java Server Pages, realizującej funkcję View (3). Komponent View pobiera wyniki pracy funkcji logiki biznesowej z obiektów Model (4). Komponent View generuje wynikowy dokument dla użytkownika (5).

24 Wzorzec MVP Wzorzec architektury interfejsu użytkownika zarezerwowany dla aplikacji typu Rich Client Application (lub RIA) Interakcja View  Presenter model Widok i prezenter są połączone 1-1 (jeden prezenter ma jeden widok) Logikę obsługuje prezenter, to on rejestruje się na powiadomienia, tworzy model Widok ma tylko warstwę prezentacji (sterowaną przez prezenter) Widok jest wstrzykiwany do prezentera przez interfejs

25 Implementacja JavaFX VIEW jest to Stage – obiekt dostarczany przez FX posiadający obiekt Scene, będący korzeniem drzewa widoku. Scenę definiujemy przez plik fxml. CONTROLLER – klasa implementująca interfejs Initializable. MODEL – klasa zawierająca stan aplikacji public class Stock { protected String symbol; protected String name; public Stock(String symbol, String name) { this.symbol = symbol; this.name = name; } public String getSymbol() { return symbol; public String getName() { return name;

26 Implementacja JavaFX Interfejs i jego implementacja - model
public interface StockPriceUpdatedListener { public void priceUpdated( Stock stock, double price ); } public class StockModel implements StockPriceUpdatedListener { /*deklaracje pól... */ public StringProperty addStock( Stock stock ) { /*metoda dodania produktu */ } @Override public void priceUpdated(Stock stock, double price) { /*metoda altualizacji produktu */

27 Implementacja JavaFX Widok – tworzony jest poprzez SceneBuilder. Jego wynikiem jest plik FXML. Między innymi zawiera ten plik instrukcje typu <Button fx:id="subscribeButton" layoutX="136.0" layoutY="153.0" mnemonicParsing="false" onAction="#subscribeButtonClicked" text="Subscribe" /> Fragmenty klasy Kontrolera public class StockPricePanelController implements Initializable { @FXML protected Button subscribeButton; protected StockModel stockModel; public void subscribeButtonClicked( ActionEvent event ) { /* metoda obsługująca kliknięcie */ }


Pobierz ppt "Wykład 3a Działanie aplikacji okienkowej"

Podobne prezentacje


Reklamy Google