Ćwiczenia 1 Winapi, gdi



Pobieranie 53.07 Kb.
Data02.05.2016
Rozmiar53.07 Kb.

Ćwiczenia 1

WinAPI, GDI



Win32API


Po uruchomieniu Visual Studio 2005 załóż nowy projekt.

Projekt ma się znajdować na dysku D i powinien nazywać się SimpleGDI. Typ projektu to Win32.

W kolejnym oknie, w zakładce Application Settings zaznacz „Empty project”

Do projektu dodaj nowy plik o nazwie main.cpp. W tym celu kliknij prawym przyciskiem na projekt w drzewie folderów znajdującym się po lewej stronie, wybierz Add->New Item. W kolejnym oknie wpisz nazwę pliku i zaznacz C++ File.




Stworzenie prostego okna wymaga umieszczenia w pliku main.cpp następującego kodu:

//////////////////////////////////////////////////////////////////////////

#include //Plik naglowkowy zawierający definicje funkcji, typy danych oraz makra WinAPI
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )

{

MSG msg ;



HWND hWnd;

WNDCLASS wndClass;

wndClass.style = CS_HREDRAW | CS_VREDRAW; //Styl okna - bedzie sie odmalowywalo przy kazdym przesunieciu lub zmianie rozdzielczosci

wndClass.lpfnWndProc = WndProc; //Wskazujemy procedure przetwarzajaca komunikaty okna

wndClass.cbClsExtra = 0;

wndClass.cbWndExtra = 0;

wndClass.hInstance = hInstance; //Ustawiamy w oknie instancje naszego programu

wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Ladujemy z zasobow systemowych

wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Domyslny kursor i ikone

wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // Kolor tla okna

wndClass.lpszMenuName = NULL; // Nie tworzymy menu

wndClass.lpszClassName = TEXT("GettingStarted"); // Nazwa klasy okna, wyswietlana w naglowku okna


RegisterClass(&wndClass); //Rejestrujemy klase okna w systemie

hWnd = CreateWindow(

TEXT("GettingStarted"), // window class name

TEXT("Getting Started"), // window caption

WS_OVERLAPPEDWINDOW, // window style

CW_USEDEFAULT, // initial x position

CW_USEDEFAULT, // initial y position

800, // initial x size

600, // initial y size

NULL, // parent window handle

NULL, // window menu handle

hInstance, // program instance handle

NULL); // creation parameters

RECT rect = { 0, 0, 800, 600 }; //Tworzymy prostokat o wymiarach 800x600

AdjustWindowRect( &rect, GetWindowLong( hWnd, GWL_STYLE ), FALSE ); //Skalujemy okno tak aby obszar roboczy faktycznie mial 800x600px

SetWindowPos( hWnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE );


ShowWindow(hWnd, nCmdShow); //Wyswietlamy okno

UpdateWindow(hWnd);


/*

Ponizej znajduje sie petla wiadomosci. Odbieramy

wiadomosci od systemu za pomoca funkcji GetMessage

i przekazujemy je do procedury okna.

*/

while( GetMessage(&msg, NULL, 0, 0)) {



DispatchMessage(&msg);

}
return (int) msg.wParam;

}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )



{
// Obslugujemy tylko wiadomosc WM_DESTROY oznaczajaca zamkniecie okna.

switch(msg)

{

case WM_DESTROY:



PostQuitMessage(0); // Ta funkcja dodaje do kolejki wiadomosci WM_QUIT

return 0;

}
// wszystkie inne wiadomosci sa obslugiwane w sposob domyslny

return DefWindowProc(hwnd, msg, wParam, lParam);

}

//////////////////////////////////////////////////////////////////////////




GDI

Jest to niezależny od sprzętu interfejs programistyczny umożliwiający rysowanie prostej grafiki 2D na urządzenia wyjściowe.

Do części nagłówkowej pliku main.cpp należy dopisać następujący kod:

#pragma comment(lib, "gdiplus.lib") // Dolaczamy biblioteke gdiplus


#include //Plik naglowkowy zawierający definicje funkcji, typy danych oraz makra WinAPI

#include //Plik naglowkowy GDIPlus


using namespace Gdiplus; //Uzywamy przestrzeni nazw GDI

Natomiast aby zainicjować GDI+ w programie przed wywołaniem funkcji ShowWindow(..) należy dopisać


GdiplusStartupInput gdiplusStartupInput; //Struktura zawierajaca parametry startowe

ULONG_PTR gdiplusToken; // Wskaznik pod ktory zostanie przypisany token


// Initializacja GDI

GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


Zainicjowane GDI+ należy zamknąć na koniec pracy aplikacji, tak więc po pętli wiadomości należy wywołać funkcję
GdiplusShutdown(gdiplusToken);
Kolejnym krokiem będzie obsłużenie wiadomości WM_PAINT, która oznacza że okno powinno się odmalować.
Nowsza wersja WndProc powinna wyglądać następująco:
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )

{
HDC hdc;

PAINTSTRUCT ps;
switch(msg)

{

case WM_PAINT:



hdc = BeginPaint(hwnd, &ps);

OnPaint(hdc);

EndPaint(hwnd, &ps);

return 0;


case WM_DESTROY:

PostQuitMessage(0); // Ta funkcja dodaje do kolejki wiadomosci WM_QUIT

return 0;

}
// wszystkie inne wiadomosci sa obslugiwane w sposob domyslny

return DefWindowProc(hwnd, msg, wParam, lParam);

}
Funkcja EndPaint(…) jest częścią interfejsu WinAPI i powinna być wywoływana na koniec rysowania w oknie. Funkcję OnPaint(…) musimy stworzyć sami. To w niej będzie odbywało się całe rysowanie. Powinna być zadeklarowana nad funkcją WndProc i powinna wyglądać tak:


VOID OnPaint(HDC hdc)

{

}


Rysowanie linii


Do narysowania linii za pomocą GDI+ konieczne jest stworzenie obiektu Graphics oraz obiektu Pen definiującego atrybuty linii. Samą linię rysuje się metodą DrawLine(…) z klasy Graphics.
Graphics graphics(hdc);

Pen pen(Color(255, 0, 0, 0)); //Konstruktor przyjmuje kolor w formacie ARGB


graphics.DrawLine(&pen, 0 , 0, 800, 600); //argumenty to obiekt Pen, x1, y1, x2, y2
Powyższy kod po umieszczeniu w funkcji OnPaint(…) narysuje czarną linię z lewego górnego rogu okna do prawego dolnego.

Rysowanie prostokątów


Potrzebny będzie obiekt SolidBrush (ponieważ chcemy żeby prostokąt był wypełniony kolorem). Prostokąt rysujemy za pomocą metody FillRectangle, jako argumenty przekazując referencję na obiekt SolidBrush oraz koordynaty lewego górnego wierzchołka, szerokość oraz wysokość.
Graphics graphics(hdc);

SolidBrush solidBrush(Color(255, 0, 0, 0));

graphics.FillRectangle(&solidBrush, 100, 100, 30, 10);
Powyższy kod rysuje czarny prostokąt o rozmiarze 30 na 10 px na pozycji (100, 100).

Tworzenie struktur w C++


Strukturę o nazwie MojaStruktura deklarujemy w sposób następujący
struct MojaStruktura

{

MojaStruktura()



{

mMojaLiczba =100;

}
int mMojaLiczba;

};
W metodzie MojaStruktura(), będącej konstruktorem, ustawiamy wartość domyślną atrybutu mMojaLiczba na 100.


Obiekty takiej struktury tworzymy w następujący sposób:
MojaStruktura struktura1;

struktura1.mMojaLiczba = 30;



Tablice w C++


Stworzenie tablicy 10 struktur z poprzedniego paragrafu odbywa się w następujący sposób:
MojaStruktura tablicaStruktur[10];
Tablica ta ma rozmiar 10 elementów i jest indeksowana od 0. Tak więc aby ustawić wartośc atrybutu mMojaLiczba w 5 elemencie tablicy na wartość 15 piszemy:
tablicaStruktur[4].mMojaLiczba = 15;
Dwuwymiarowe tablice tworzone i indeksowane są w sposób analogiczny. Tablica liczb całkowitych o wymiarach 3x4 jest tworzona w sposób następujący:
int tablica[3][4];


Pętle for w C++


Pętle typu for pozwalają wykonać pewien fragment kodu określoną ilość razy. Deklaracja pętli składa się z trzech pól oddzielonych średnikami. W pierwszym polu można zadklarować zmienną od której uzależniona będzie praca pętli. W kolejnym polu deklarowany jest warunek działania pętli. Ostatnie pole to krok pętli, czyli operacja wykonywana co krok pętli.
for(int i =0; i< 10; i = i + 1)

{

graphics.DrawLine(&pen, i , 0, i, 600);



}
Powyższy kod narysuje 10 pionowych linii o długości 600 pix obok siebie. Pętla zbudowana jest w następujący sposób: ma rozpocząć pracę od wartości 0, pracować do momentu gdy zmienna i zrówna się lub przekroczy wartość 10 i co krok ma zwiększac wartość zmiennej i o 1.

Kod, który ma być wykonywany za każdym krokiem pętli znajduje się w nawiasach klamrowych pod deklaracją pętli. Jak widać, zmienna i została wykorzystana do modyfikacji argumentów metody DrawLine, dzięki czemu każda kolejna linia jest rysowana na innej pozycji.



Zadanie 1


Napisz funkcję DrawGrid(HDC hdc), która będzie rysowała siatkę z 40 pionowych i 30 poziomych linii znajdujących się w odstępach 20pix od siebie.

Zadanie 2


Napisz funkcję DrawPixel(HDC hdc, int x, int y, int blackness), która będzie rysowała prostokąt o wymiarach 19x19 w punkcie (x, y) o kolorze czarnym i wartości alfa równej blackness.

Zadanie 3


Stwórz strukturę MyPixel zawierającą jeden atrybut typu liczba całkowita o nazwie mBlackness.

Zadanie 4


Stwórz dwuwymiarową globalną (zadeklarowaną poza ciałem funkcji) tablicę obiektów MyPixel o nazwie mFrontBuffer. Tablica powinna mieć rozmiar 40 na 30. Obiekty w tej tablicy będą reprezentować „piksele” na siatce z zadania 1.

Zadanie 5


Napisz funkcję Present(HDC hdc) która narysuje wszystkie obiekty MyPixel z tablicy mFrontBuffer.


©absta.pl 2016
wyślij wiadomość

    Strona główna