VisualCPP1, 1


  1. Otwieramy Visual Studio 2008

  2. Wybieramy z menu File - New Project

  3. Wybieramy typ projektu MFC, oraz szablon (template) MFC Application

  4. Wpisujemy nazwe projektu np. Labiryncik, klikamy OK

  5. Proszę skompilować (F7) oraz uruchomić aplikację (F5)

  6. Zaglądamy do widoku plików (Solution Expolorer lub File View). Widać że Visual C++ wygenerował dla nas DUŻO klas, dużo kodu źródłowego.

  7. Teraz, aplikacja wygenerowana przez Visual C++ składa się między innymi z następujących klas:

Klasa Dokumentu

CLabiryncikDoc - w klasie tej należy umieścić wszelkiego rodzaju dane które będą używane przez nasz program

Klasa Widoku

CLabiryncikView - w klasie tej należy umieścić wszelkiego rodzaju procedury które będą prezentować (wypisywać, rysować) nasze dane

W jaki sposób rozdzielić nasz labirynt pomiędzy klasę widoku i klasę dokumentu?

Zaglądnijmy do pliku nagłówkowego Labirynt.h który już kiedyś napisaliśmy

class Labirynt

{

public:

Labirynt(void);

//tablica z danymi labiryntu

char* m_labirynt[13];

//polozenie ludzika

int m_wiersz;

int m_kolumna;

//metoda wypiujace labirynt

void WypiszLabirynt();

};

oraz do pliku z kodem źródłowym Labirynt.cpp

#include <iostream>

using namespace std;

Labirynt::Labirynt(void)

{

m_labirynt[0] = "*************";

m_labirynt[1] = "* * * *";

m_labirynt[2] = "* *** *** * *";

m_labirynt[3] = "* * *";

m_labirynt[4] = "* * * *******";

m_labirynt[5] = "* * * * ";

m_labirynt[6] = "*** *** * ***";

m_labirynt[7] = "* * * * *";

m_labirynt[8] = "* *** * *** *";

m_labirynt[9] = "* * * * *";

m_labirynt[10] = "* * * * *** *";

m_labirynt[11] = "* * * *";

m_labirynt[12] = "*************";

m_wiersz=9;

m_kolumna=1;

}

void Labirynt::WypiszLabirynt()

{

for(int i=0;i<13;i++) {

if(i==m_wiersz) {

for(int j=0;j<m_kolumna;j++) cout << m_labirynt[i][j];

cout << "X";

for(int j=m_kolumna+1;j<13;j++) cout << m_labirynt[i][j];

}

else

cout << m_labirynt[i];

}

}

Jak rozdzielić tą klasę pomiędzy Klasę Dokumentu i Klasę Widoku?

Co stanowi tutaj dane, a co stanowi procedurę prezentowania tych danych?

  1. W pliku nagłówkowym CLabiryncikDoc.h klasy dokumentu CLabiryncikDoc proszę znaleźć sekcję attributes (atrybuty) oraz dopisać dane labiryntu:

// Attributes

public:

//tablica z danymi labiryntu

char* m_labirynt[13];

//polozenie ludzika

int m_wiersz;

int m_kolumna;

Proszę uważać żeby nie zmienić niczego innego w pliku !

  1. W pliku z kodem zródłowym CLabiryncikDoc.cpp klasy dokumentu CLabiryncikDoc proszę znaleźć konstruktor klasy i dopisać w nim wypełnianie klasy labiryntu:

// CLabiryncikDoc construction/destruction

CLabiryncikDoc::CLabiryncikDoc()

{

m_labirynt[0] = "*************";

m_labirynt[1] = "* * * *";

m_labirynt[2] = "* *** *** * *";

m_labirynt[3] = "* * *";

m_labirynt[4] = "* * * *******";

m_labirynt[5] = "* * * * ";

m_labirynt[6] = "*** *** * ***";

m_labirynt[7] = "* * * * *";

m_labirynt[8] = "* *** * *** *";

m_labirynt[9] = "* * * * *";

m_labirynt[10] = "* * * * *** *";

m_labirynt[11] = "* * * *";

m_labirynt[12] = "*************";

m_wiersz=9;

m_kolumna=1;

}

Proszę uważać żeby nie zmienić niczego innego w pliku !

  1. Proszę w pliku nagłówkowym CLabiryncikView.h klasy widoku CLabiryncikView
    znaleźć sekcję z operacjami (procedurami) i dopisać nagłówek procedury WypiszLabirynt

// Operations

public:

void WypiszLabirynt();

Proszę uważać żeby nie zmienić niczego innego w pliku !

  1. Proszę w pliku z kodem źródłowym CLabiryncikView.cpp klasy widoku CLabiryncikView odnaleźć konstruktor i destruktor klasy CLabiryncikView i dopisać za nimi procedurę WypiszLabirynt.

void CLabiryncikView::WypiszLabirynt()

{

for(int i=0;i<13;i++) {

cout << m_labirynt[i];

}

}

Proszę zwrócić uwagę że procedura WypiszLabirynt jest teraz składową klasy CLabiryncikView.

Proszę uważać żeby nie zmienić niczego innego w pliku !

  1. Proszę spróbować skompilować program.
    Między innymi otrzymujemy następujące błędy:

1>c:\users\maciek\documents\visual studio 2008\projects\labiryncik\labiryncik\labiryncikview.cpp(42) : error C2065: 'm_labirynt' : undeclared identifier

Na czym polega problem?

Nie kompiluje się procedura WypiszLabirynt.

W jakiej klasie umieściliśmy procedurę WypiszLabirynt?

W jakiej klasie umieszczone zostały zmienne (atrybuty) m_wiersz, m_kolumna, oraz tablica m_labirynt??? W tej samej?

  1. Musimy umieć dostać się z klasy widoku do klasy dokumentu.

Jeśli jesteśmy w klasie widoku, możemy dostać wskaźnik do klasy dokumentu pisząc

CLabiryncikDoc* pDoc = GetActiveDocument();

Jeśli jesteśmy natomiast w klasie dokumentu, i chcemy dostać wskaźnik do klasy widoku, musimy najpierw dostać wskaźnik do obiektu reprezentującego nasze okienko, i dopiero na końcu wskaźnik do obiektu widoku.

CMainFrame *pFrame = (CMainFrame*) AfxGetMainWnd();

CLabiryncikView *pView =
(CLabiryncikView*) pFrame->GetActiveView();

Proszę w procedurze WypiszLabirynt, dopisać na początku pobranie wskaźnika do klasy dokumentu.

Następnie przed odwołaniem do m_labirynt, proszę dopisać pDoc->, np. zamieniamy m_labirynt na pDoc->m_labirynt

  1. Proszę skompilować program. Należy jeszcze na początku pliku CLabiryncikView.cpp dopisać

#include <iostream>

using namespace std;

najlepiej przed

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

Ponadto należy znaleźć w pliku CLabiryncikView.cpp procedurę OnDraw i dopisać w niej wywołanie WypiszLabirynt:

// CLabiryncikView drawing

void CLabiryncikView::OnDraw(CDC* /*pDC*/)

{

CLabiryncikDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;

// TODO: add draw code for native data here

WypiszLabirynt();

}

Proszę spróbować skompilować i uruchomić program.

Wszystko działa tylko nic się nie rysuje!

Dlaczego ? Bo teraz mamy okienko graficzne a nie okienko tekstowe.

W okienku graficznym pisze / rysuje się w zupełnie inny sposób.

  1. Musimy napisać procedurę WypiszLabirynt od nowa:

void CLabiryncikView::WypiszLabirynt(CDC* pDC)

{

CLabiryncikDoc* pDoc = GetDocument();

int poczatek_x = 5;

int poczatek_y = 5;

for(int i=0;i<13;i++) {

CString tekst(pDoc->m_labirynt[i]);

CSize size = pDC->GetTextExtent(tekst);

CRect rect(poczatek_x,poczatek_y,

poczatek_x+size.cx,poczatek_y+size.cy);

int format = DT_CENTER;

pDC->DrawText(tekst,&rect,format);

poczatek_y += size.cy;

}

}

Proszę skompilować i uruchomić program.

Czy wszystko jest w porządku?

Musimy przekazać nowy parametr CDC* pDC - to jest rysowacz który służy do rysowania w okienku. Musimy zmienić program w trzech miejscach:

W procedurze OnDraw należy odkomentować pDC oraz przekazać do procedury WypiszLabirynt

void CLabiryncikView::OnDraw(CDC* pDC)

{

CLabiryncikDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;

// TODO: add draw code for native data here

WypiszLabirynt(pDC);

}

W pliku nagłówkowym CLabiryntView.h klasy CLabiryntView należy dopisać pDC do nazwy procedury WypiszLabirynt:

// Operations

public:

void WypiszLabirynt(CDC* pDC);

Proszę skompilować i uruchomić program.

Czy wszystko jest w porządku?

  1. Problem polega na tym, że spacje i gwiazdki mają różną długość w trybie graficznym, i właściwie zamiast wypisywać labirynt powinniśmy go narysować...Musimy napisać nową procedurę NarysujLabirynt która naprawdę bedzie rysowała labirynt.

  2. Proszę w pliku nagłówkowym CLabiryncikView.h klasy widoku CLabiryncikView
    znaleźć sekcję z operacjami (procedurami) i dopisać nagłówek procedury NarysujLabirynt

// Operations

public:

void WypiszLabirynt();

void NarysujLabirynt(CDC *pDC);

  1. Proszę w pliku z kodem źródłowym CLabiryncikView.cpp klasy widoku CLabiryncikView odnaleźć konstruktor i destruktor klasy CLabiryncikView i dopisać za nimi procedurę NarysujLabirynt.

void CLabiryncikTestView::NarysujLabirynt(CDC* pDC)

{

CLabiryncikTestDoc* pDoc = GetDocument();

//pobieramy rozmiar okna

CRect okno;

GetClientRect(&okno);

//szerokosc pola = 1/30 szerokosci okno

int dx = okno.right/30;

//wysokosc pola = 1/30 wysokosci okna

int dy = okno.bottom/30;

//punkt w ktorym bedzie znajdowac sie srodek pierwszego pola labiryntu

CPoint pierwsze_pole(2*dx,2*dy);

//petla po wierszach z tablicy labiryntu

for(int i=0;i<13;i++)

//petla po kolumnach z tablicy labiryntu

for(int j=0;j<13;j++) {

//punkt w ktorym znajduje sie srodek pola [i][j] labiryntu

CPoint pole(pierwsze_pole.x+j*2*dx, pierwsze_pole.y+i*2*dy);

if(pDoc->m_labirynt[i][j]=='*'){

//rozmiar cegielki

CRect cegielka(pole.x-dx,pole.y-dy,pole.x+dx,pole.y+dy);

//pedzel do zamalowania cegielki

CBrush pedzel(RGB(255,0,0));

//rysujemy cegielke

pDC->FillRect(&cegielka,&pedzel);

}

}

}

  1. Proszę dorysować ludzika w labiryncie. Dopisujemy w procedurze RysujLabirynt

if(pDoc->m_wiersz==i && pDoc->m_kolumna==j){

//rozmiar elipsy

CRect ludzik(pole.x-dx/2,pole.y-dy/2,pole.x+dx/2,pole.y+dy/2);

//rysujemy elipse

pDC->Ellipse(&ludzik);

pDC->MoveTo(pole.x,pole.y);

pDC->LineTo(pole.x+dx/2,pole.y+dy/2);

pDC->MoveTo(pole.x,pole.y);

pDC->LineTo(pole.x-dx/2,pole.y+dy/2);

pDC->MoveTo(pole.x,pole.y);

pDC->LineTo(pole.x,pole.y+dy/2);

pDC->MoveTo(pole.x,pole.y+dy/2);

pDC->LineTo(pole.x+dx/2,pole.y+dy);

pDC->MoveTo(pole.x,pole.y+dy/2);

pDC->LineTo(pole.x-dx/2,pole.y+dy);

}

  1. Proszę w klasie dokumentu CLabiryncikDoc dodać procedury WLewo, WPrawo, WGore, WDol które będą sprawdzały czy da się przesunąć ludzika w odpowiednią stronę, i jeśli się da, to będą go przesuwały, np.

void CLabiryncikTestDoc::WLewo()

{

if(m_labirynt[m_wiersz][m_kolumna-1]==' ')m_kolumna--;

}

  1. Dodamy teraz przyciski do kierowania ludzikiem.

Proszę otworzyć z lewej strony Solution Explorer (lub File View) kliknąć dwa razy na Labiryncik.rc
Otworzy się przeglądarka zasobów.

Proszę kliknąć prawym przyciskiem myszy na projekcie i wybrać Add - Resource - Dialog, kliknąć New.

Proszę na Toolbox'ie wybrać Button (przycisk) i narysować cztery nowe buttony na okienku dialogowym.

Proszę kliknąć prawym przyciskiem myszy na przycisku, wybrać Properties i zmienić Caption na Góra, Dół, Lewo i Prawo.

Proszę kliknąć dwa razy myszą na dowolnym przycisku. Pojawi się okienko kojarzenia nazwy klasy z oknem dialogowym. Proszę wpisać nazwę klasy Sterownik.

  1. Proszę teraz otworzyć nagłówek Sterownik.h i dopisać:

Sterownik(CWnd* pParent,CDocument* pDoc,

CView *pView); // standard constructor

//atributes

CDocument* m_pDoc;

CView *m_pView;

Proszę otworzyć plik źródłowy Sterownik.cpp i dopisać w konstruktorze:

Sterownik::Sterownik(CWnd* pParent, CDocument* pDoc, CView* pView)

: CDialog(Sterownik::IDD, pParent)

{

m_pView=pView;

m_pDoc=pDoc;

}

  1. Proszę teraz dwu-klikać kolejno na wszystkich czterech przyciskach - otworzy

nam się wówczas program który uruchomiony zostanie gdy ktoś wciśnie przycisk podczas działania programu. Proszę wpisać odpowiednio:

((CLabiryncikTestDoc*)m_pDoc)->WGore();

((CLabiryncikTestView*)m_pView)->Invalidate();

lub

((CLabiryncikTestDoc*)m_pDoc)->WDol();

((CLabiryncikTestView*)m_pView)->Invalidate();

lub

((CLabiryncikTestDoc*)m_pDoc)->WLewo();

((CLabiryncikTestView*)m_pView)->Invalidate();

lub

((CLabiryncikTestDoc*)m_pDoc)->WPrawo();

((CLabiryncikTestView*)m_pView)->Invalidate();

Proszę też na początku tego pliku dopisać:

#include "MainFrm.h"

#include "LabiryncikTestDoc.h"

#include "LabiryncikTestView.h"

  1. Musimy wreszcie podczas uruchamiania programu stworzyć nasze okno dialogowe do kierowania ludzikiem.

Proszę otworzyć z lewej strony Solution Explorer (lub File View) kliknąć dwa razy na Labiryncik.rc
Otworzy się przeglądarka zasobów.

Wchodzimy do pola Menu, wybieramy IDR_LABIRYNCIK i dopisujemy do menu pole Start.

Z przyciskiem tym bedzie skojarzone zdarzenie ID_FILE_START

  1. Musimy teraz dodać procedurę obsługi zdarzenia związanego z wybraniem tej opcji menu (chcemy wtedy otworzyć okno dialogowe do kierowania ludzikiem)

Klikamy prawym przyciskiem myszy na menu Start, i wybieramy AddEventHandler (dodaj procedurę obsługi zdarzenia)

Na liście klas wybieramy CLabiryncikView.

Pojawi się nam procedura która zostanied uruchomiona po wybraniu menu Start.

Odpalamy w niej nasze okienko do kierowania ludzikiem:

void CLabiryncikView::OnFileStart()

{

Sterownik okno(NULL,GetDocument(),this);

okno.DoModal();

}

Pamiętamy też o dopisaniu z przodu pliku:

#include "Sterownik.h"

  1. Proszę skompilować i uruchomić program

  2. Proszę zmienić sposób rysowania ludzika.

  3. Proszę podmienić labirynt na swój własny.

0x08 graphic

  1. Chcemy teraz zmienić sposób rysowania labiryntu, tak aby jego ściany miały zerową grubość.
    W tym celu musimy dodać nowy sposób kodowania labiryntu - za pomocą tablicy kodów.

0x01 graphic

W pliku nagłówkowym CLabiryncikDoc.h klasy dokumentu CLabiryncikDoc dodajemy tablice dwuwymiarowa liczb

// Attributes

public:

//tablica z danymi labiryntu

char* m_labirynt[13];

//tablica z kodami scian

int m_kody[6][6];

//polozenie ludzika

int m_wiersz;

int m_kolumna;

  1. Musimy wypełnić tą tablicę kodami. UWAGA - zrobimy to automatycznie, na podstawie tablicy tekstów kodującej labirynt. Napiszemy procedurę WypelnijKodyLabiryntu(). W pliku nagłówkowym CLabiryncikDoc.h klasy CLabirynicikDoc szukamy sekcji Operations i dodajemy nagłówek procedury

// Operations

public:

//procedura oblicza kody scian dla pol labiryntu

void WypelnijKodyLabiryntu();

  1. W pliku z kodem źródłowym CLabiryncikDoc.cpp klasy CLabirynicikDoc szukamy konstruktora i dopisujemy za nią procedurę WypelnijKodyLabiryntu

void CLabiryncikTestDoc::WypelnijKodyLabiryntu()

{

//petla po wierszach z tabeli kodow

for(int i=0;i<6;i++)

//petla po kolumnach z tabeli kodow

for(int j=0;j<6;j++)

{

int w = 2*i+1; //wiersz w tablicy tekstow

int k = 2*j+1; //kolumna w tablicy tekstow

if(m_labirynt[w][k+1]==' ' && m_labirynt[w+1][k]==' ' &&

m_labirynt[w][k-1]==' ' && m_labirynt[w-1][k]==' ')

m_kody[i][j]=0;

if(m_labirynt[w][k+1]=='*' && m_labirynt[w+1][k]==' ' &&

m_labirynt[w][k-1]==' ' && m_labirynt[w-1][k]==' ')

m_kody[i][j]=1;

if(m_labirynt[w][k+1]==' ' && m_labirynt[w+1][k]=='*' &&

m_labirynt[w][k-1]==' ' && m_labirynt[w-1][k]==' ')

m_kody[i][j]=2;

PROSZE TUTAJ DOPISAC USTAWIANIE POZOSTALYCH KODOW

}//koniec petli po kolumnach

}

0x01 graphic

  1. Gdzie należy zawołać procedurę WypełnijKodyLabiryntu?
    W konstruktorze klasy dokumentu CLabiryncikDoc dopisujemy

CLabiryncikTestDoc::CLabiryncikTestDoc()

{

m_labirynt[0] = "*************";

m_labirynt[1] = "* * * *";

m_labirynt[2] = "* *** *** * *";

m_labirynt[3] = "* * *";

m_labirynt[4] = "* * * *******";

m_labirynt[5] = "* * * * ";

m_labirynt[6] = "*** *** * ***";

m_labirynt[7] = "* * * * *";

m_labirynt[8] = "* *** * *** *";

m_labirynt[9] = "* * * * *";

m_labirynt[10] = "* * * * *** *";

m_labirynt[11] = "* * * *";

m_labirynt[12] = "*************";

m_wiersz=9;

m_kolumna=1;

WypelnijKodyLabiryntu();

}

  1. Proszę teraz ustawić pułapkę (klawisz F9) w procedurze WypelnijKodyLabiryntu,

skompilować i uruchomić program klawiszem F7 i potem F5, i sprawdzić czy procedura dobrze wypełnia tablicę kodów (proszę sprawdzić przynajmniej 2 wiersze).

Kody powinny wyglądać następująco:

{ 5,13, 5,10, 8,12},

{ 3, 4, 1,11, 2, 6},

{14, 9, 7, 8, 5,13},

{ 5, 6,12, 9, 7, 8},

{ 9,12, 9, 3,10, 1},

{ 7, 6, 7, 6,11, 6}

  1. Proszę w pliku nagłówkowym CLabiryncikView.h klasy widoku CLabiryncikView
    znaleźć sekcję z operacjami (procedurami) i dopisać nagłówek procedury NarysujCienkiLabirynt

// Operations

public:

void WypiszLabirynt();

void NarysujCienkiLabirynt(CDC *pDC);

  1. Proszę w pliku z kodem źródłowym CLabiryncikView.cpp klasy widoku CLabiryncikView odnaleźć konstruktor i destruktor klasy CLabiryncikView i dopisać za nimi procedurę NarysujCienkiLabirynt.

void CLabiryncikTestView::NarysujCienkiLabirynt(CDC* pDC)

{

CLabiryncikTestDoc* pDoc = GetDocument();

//szerokosc pola

int dx = 30;

//wysokosc pola

int dy = 30;

//punkt w ktorym bedzie znajdowac sie srodek pierwszego pola labiryntu

CPoint pierwsze_pole(2*dx,2*dy);

//petla po wierszach z tablicy kodow

for(int i=0;i<6;i++)

//petla po kolumnach z tablicy kodow

for(int j=0;j<6;j++) {

//punkt w ktorym znajduje sie srodek pola [i][j] labiryntu

CPoint pole(pierwsze_pole.x+j*2*dx, pierwsze_pole.y+i*2*dy);

int kod = pDoc->m_kody[i][j];

//przypadki dla ktorych trzeba narysowac gorna sciane

if(kod==4 ||kod==5 ||kod==8 ||kod==10 ||kod==11 ||kod==12 ||kod==13)

{

pDC->MoveTo(pole.x-dx,pole.y-dy);

pDC->LineTo(pole.x+dx,pole.y-dy);

}

//przypadki dla ktorych trzeba narysowac prawa sciane

if(kod==1 ||kod==6 ||kod==8 ||kod==9 ||kod==12 ||kod==13 ||kod==14)

{

PROSZE TUTAJ DOPISAC RYSOWANIE PRAWEJ SCIANY

}

//przypadki dla ktorych trzeba narysowac dolna sciane

PROSZE TUTAJ DOPISAC SPRAWDZANIE I RYSOWANIE DOLNEJ SCIANY

//przypadki dla ktorych trzeba narysowac lewa sciane

PROSZE TUTAJ DOPISAC SPRAWDZANIE I RYSOWANIE LEWEJ SCIANY

}

}

  1. Proszę skompilować i uruchomić program. Czy labirynt dobrze się rysuje?
    Jeśli nie, to proszę ustawić pułapkę w procedurze NarysujLabirynt (klawisz F9), proszę skompilować i uruchomić program klawiszami F7 i F5. Proszę poprawić ewentualne błędy rysowania, tak żeby labirynt dobrze się rysował.

  2. Proszę dodać rysowanie ludzika w nowej procedurze NarysujCienkiLabirynt

  3. Proszę zmodyfikować odpowiednio procedury WGore, WDol, WLewo, WPrawo (jak to zrobić?)



Wyszukiwarka

Podobne podstrony:
Lab 2 Visual Analyser oraz kompresje v2
ASP NET 2 0 Tworzenie witryn internetowych z wykorzystaniem C i Visual Basica aspntw
Visual Basic Przykładowe zadania , Studia i nauka, Visual Basic
Visual1
Programowanie w Visual?sic dla Excel
Visual?sic lekacje
Lab6, Visual Basic Lab 6a, Visual Basic Lab 3
Leksykon VISUAL BASIC, r00-05, Rozdział X
MS Visual C Ćwiczenia
Visual Basic Zdarzenia , Studia i nauka, Visual Basic
67 Audio and Visual System
adudczak visualvm
Visual 5
Visualization Exercises
Visual3
visual methodologies chapter4 content analysis pages 1 5

więcej podobnych podstron