LEKCJA47.TXT

(7 KB) Pobierz
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);  
}  
________________________________________________________________ 
 
Zgłoś jeśli naruszono regulamin