lekcjaG ZLXVIAWSSEMJ5QXWJ3XAYJBYKZY2PHNH7UED3BA


LEKCJA 47

APLIKACJA OBIEKTOWA - RYSOWANIE W OKNIE.

W trakcie tej lekcji opracujemy obiektową aplikację psoługując się biblioteką klas Object Windows Library.

Zaczniemy oczywiście od standardowych "klocków". Definicja klasy Nasza_Aplikacja i moduł prezentacyjno - uruchomieniowy będą wyglądać standardowo, nie musimy im zatem poświęcać zbytniej uwagi. Przytoczymy je jedynie. Pointer do napisu inicjujemy po to, by okienko komunikatu zawierało jakąś bardziej konkretną informację dla użytkownika. Rysunki z wnętrza tej aplikacji można przy pomocy Schowka przenieść jako pliki .CLP, bądź za pomocą PAINTBRUSH - jako .BMP, .PCX i drukować.

#include <owl.h>

LPSTR Ptr = "Jesli chcesz zapamietac rysunek, \

powinienes przeniesc go do Clipboard'u \

klawiszami [Print Screen] \

lub [Alt]+[PrtScr].";

class TNAplikacja : public TApplication

{

public:

TNAplikacja(LPSTR AName, HANDLE hInstance, HANDLE

hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

: TApplication(AName, hInstance, hPrevInstance, lpCmdLine,

nCmdShow) {};

virtual void InitMainWindow();

};

...

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

{

TNAplikacja OBIEKT("Rysownik. Prawy klawisz umozliwia wyjscie.",

hInstance, hPrevInstance, lpCmdLine, nCmdShow);

OBIEKT.Run();

return (OBIEKT.Status);

}

Nic specjalnie ciekawego nie dzieje się w funkcji inicjującej główne okno, ani w funkcji zamykającej aplikację. Zmieniły się tylko napisy w okienku komunikatów.

void TNAplikacja::InitMainWindow()

{

MainWindow = new TGOkno(0, Name);

}

BOOL TGOkno::CanClose()

{

return (MessageBox(HWindow, Ptr, "KONIEC",

MB_YESNO | MB_ICONQUESTION) == IDYES);

}

Zajmiemy się teraz główną "maszynerią" programu. Rozbudujemy obsługę komunikatów przez handlery zaimplenmentowane w klasie Główne_Okno.

_CLASSDEF(TGOkno)

class TGOkno : public TWindow

{

public:

HDC dc;

BOOL ButtonDown;

BOOL Flaga_Start;

TGOkno(PTWindowsObject AParent, LPSTR ATitle);

//Konstruktor

virtual void WMLButtonDown(RTMessage Msg)

= [WM_FIRST + WM_LBUTTONDOWN];

virtual void WMLButtonUp(RTMessage Msg)

= [WM_FIRST + WM_LBUTTONUP];

virtual void WMMouseMove(RTMessage Msg)

= [WM_FIRST + WM_MOUSEMOVE];

virtual void WMRButtonDown(RTMessage Msg)

= [WM_FIRST + WM_RBUTTONDOWN];

virtual BOOL CanClose();

};

Konstruktor przekazuje parametry do konstruktora klasy bazowej i

zeruje flagę ButtonDown - lewy klawisz myszki przyciśnięty.

TGOkno::TGOkno(PTWindowsObject AParent, LPSTR ATitle)

: TWindow(AParent, ATitle)

{

ButtonDown = FALSE;

}

Funkcja obsługująca zdarzenie WM_LBUTTONDOWN jeden raz inicjuje obsługę myszki i ustawia flagę. Funkcje SetCapture() i GetDC() załatwiją problem relacji kontekstowych i określają obszar roboczy (client area). Jeśli umieścimy te funkcje w konstruktorze za obszar client area uznany zostanie cały ekran. Po zadziałaniu tych funkcji komunikaty od myszki będą dotyczyć wyłącznie obszaru roboczego. Do naciśnięcia prawego klawisza nie będzie dostępu do "ramki" okna.

void TGOkno::WMLButtonDown(RTMessage Msg)

{

if (!Flaga_Start)

{

Flaga_Start = TRUE; //UWAGA:

SetCapture(HWindow); //Jesli zainicjujemy SetCapture()

dc = GetDC(HWindow); //w konstruktorze - mamy caly ekran

}

MoveTo(dc, Msg.LP.Lo, Msg.LP.Hi);

ButtonDown = TRUE;

}

Funkcja MoweTo() powoduje przesunięcie kursora graficznego do aktualnej pozycji myszki (już względnej - z uwzględnieniem dc) bez rysowania linii. Flaga ButtnDown została ustawiona. Rysowanie scedujemy na metodę obsługującą WM_MOUSEMOVE - przesunięcie myszki.

void TGOkno::WMMouseMove(RTMessage Msg)

{

if (ButtonDown)

LineTo(dc, Msg.LP.Lo, Msg.LP.Hi);

}

Jeśli lewy klawisz jest naciśnięty - funkcja LineTo() będzie kreślić linię do kolejnych punktów "śledząc" ruch myszki. Jeśli użytkownik puści lewy klawisz - zerujemy flagę stanu klawisza ButtonDown <== FALSE.

void TGOkno::WMLButtonUp(RTMessage)

{

if (ButtonDown) ButtonDown = FALSE;

}

Jak już nabazgrzemy po ekranie, prawy klawisz umożliwi nam skasowanie zawartości przy pomocy InvalidateRect().

void TGOkno::WMRButtonDown(RTMessage)

{

InvalidateRect(HWindow, 0, 1);

ReleaseCapture();

ReleaseDC(HWindow, dc);

Flaga_Start = FALSE;

}

Para funkcji ReleaseDC() i ReleaseCapture() pozwala przekazać komunikaty od myszki do "ramki okna". Dzięki temu można po skasowaniu ekranu np. rozwinąć menu systemowe i zakończyć aplikację. A oto program w całości.

Listing. Odręczne rysowanie.

#define STRICT

#define WIN31

#include <owl.h>

LPSTR Ptr = "Jesli chcesz zapamietac rysunek, \

powinienes przeniesc go do Clipboard'u \

klawiszami [Print Screen] \

lub [Alt]+[PrtScr].";

class TNAplikacja : public TApplication

{

public:

TNAplikacja(LPSTR AName, HANDLE hInstance, HANDLE

hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

: TApplication(AName, hInstance, hPrevInstance, lpCmdLine,

nCmdShow) {};

virtual void InitMainWindow();

};

_CLASSDEF(TMyWindow)

class TMyWindow : public TWindow

{

public:

HDC dc;

BOOL ButtonDown;

BOOL Flaga_Start;

TMyWindow(PTWindowsObject AParent, LPSTR ATitle);

//Konstruktor

virtual void WMLButtonDown(RTMessage Msg)

= [WM_FIRST + WM_LBUTTONDOWN];

virtual void WMLButtonUp(RTMessage Msg)

= [WM_FIRST + WM_LBUTTONUP];

virtual void WMMouseMove(RTMessage Msg)

= [WM_FIRST + WM_MOUSEMOVE];

virtual void WMRButtonDown(RTMessage Msg)

= [WM_FIRST + WM_RBUTTONDOWN];

virtual BOOL CanClose();

};

TMyWindow::TMyWindow(PTWindowsObject AParent, LPSTR ATitle)

: TWindow(AParent, ATitle)

{

ButtonDown = FALSE;

}

void TMyWindow::WMLButtonDown(RTMessage Msg)

{

if ( !Flaga_Start )

{

Flaga_Start = TRUE; //UWAGA:

SetCapture(HWindow); //Jesli zainicjujemy SetCapture()

dc = GetDC(HWindow); //w konstruktorze - mamy caly ekran

}

MoveTo(dc, Msg.LP.Lo, Msg.LP.Hi);

ButtonDown = TRUE;

}

void TMyWindow::WMMouseMove(RTMessage Msg)

{

if ( ButtonDown )

LineTo(dc, Msg.LP.Lo, Msg.LP.Hi);

}

void TMyWindow::WMLButtonUp(RTMessage)

{

if (ButtonDown) ButtonDown = FALSE;

}

void TMyWindow::WMRButtonDown(RTMessage)

{

InvalidateRect(HWindow, NULL, TRUE);

ReleaseCapture();

ReleaseDC(HWindow, dc);

Flaga_Start = FALSE;

}

void TNAplikacja::InitMainWindow()

{

MainWindow = new TMyWindow(0, Name);

}

BOOL TMyWindow::CanClose()

{

return (MessageBox(HWindow, Ptr, "KONIEC",

MB_YESNO | MB_ICONQUESTION) == IDYES);

}

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

{

TNAplikacja OBIEKT("Rysownik. Prawy klawisz umozliwia

wyjscie.", hInstance, hPrevInstance,

lpCmdLine, nCmdShow);

OBIEKT.Run();

return (OBIEKT.Status);

}

3



Wyszukiwarka

Podobne podstrony:
Lekcja kliniczna 2 VI rok WL
Lekcja Przysposobienia Obronnego dla klasy pierwszej liceum ogólnokształcącego
Lekcja wychowania fizycznego jako organizacyjno metodyczna forma lekcji ruchu
Lekcja kliniczna nr 2 VI rok WL
04 Lekcja
PF7 Lekcja2
lekcja52
Printing bbjorgos lekcja41 uzupelnienie A
lekcja 18 id 265103 Nieznany
Hydrostatyka i hydrodynamika lekcja ze wspomaganiem komputerowym
Lekcja 6 Jak zapamietywac z notatki Tajemnica skutecznych notatek
lekcja 20
lekcja20
Lekcja 04 Szene 04
LINGO ROSYJSKI raz a dobrze Intensywny kurs w 30 lekcjach PDF nagrania audio audio kurs
Printing bbjorgos lekcja01 05 A
'Half Life', czyli pół życia przed monitorem zagrożenia medialne foliogramy gim modul 3 lekcja 5
Lekcja od mamy
lekcja 3 id 265134 Nieznany

więcej podobnych podstron