- /******************************************************************
- Grafika komputerowa, środowisko MS Windows - program przykładowy
- *****************************************************************/
- #include <windows.h>
- #include <gdiplus.h>
- #include <vector>
- using namespace Gdiplus;
- POINT bezier[] = { {750, 400}, {820, 350}, {850, 300}, {820, 250}, {800, 220}, {770, 250}, {750, 280}, {730, 250}, { 700, 220 }, {680, 250}, {650, 300}, {680, 350}, {750,400} };
- int elScale = 7;
- bool drag = false;
- bool dragDraw = false;
- int vertex = -1;
- std::vector<Point> krzywa;
- bool initialized = false;
- bool closed = false;
- //deklaracja funkcji obslugi okna
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- //funkcja Main - dla Windows
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- MSG meldunek; //innymi slowy "komunikat"
- WNDCLASS nasza_klasa; //klasa głównego okna aplikacji
- HWND okno;
- static char nazwa_klasy[] = "Podstawowa";
- GdiplusStartupInput gdiplusParametry;// parametry GDI+; domyślny konstruktor wypełnia strukturę odpowiednimi wartościami
- ULONG_PTR gdiplusToken; // tzw. token GDI+; wartość uzyskiwana przy inicjowaniu i przekazywana do funkcji GdiplusShutdown
- // Inicjujemy GDI+.
- GdiplusStartup(&gdiplusToken, &gdiplusParametry, NULL);
- //Definiujemy klase głównego okna aplikacji
- //Okreslamy tu wlasciwosci okna, szczegoly wygladu oraz
- //adres funkcji przetwarzajacej komunikaty
- nasza_klasa.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
- nasza_klasa.lpfnWndProc = WndProc; //adres funkcji realizującej przetwarzanie meldunków
- nasza_klasa.cbClsExtra = 0 ;
- nasza_klasa.cbWndExtra = 0 ;
- nasza_klasa.hInstance = hInstance; //identyfikator procesu przekazany przez MS Windows podczas uruchamiania programu
- nasza_klasa.hIcon = 0;
- nasza_klasa.hCursor = LoadCursor(0, IDC_ARROW);
- nasza_klasa.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);
- nasza_klasa.lpszMenuName = "Menu" ;
- nasza_klasa.lpszClassName = nazwa_klasy;
- //teraz rejestrujemy klasę okna głównego
- RegisterClass (&nasza_klasa);
- /*tworzymy okno główne
- okno będzie miało zmienne rozmiary, listwę z tytułem, menu systemowym
- i przyciskami do zwijania do ikony i rozwijania na cały ekran, po utworzeniu
- będzie widoczne na ekranie */
- okno = CreateWindow(nazwa_klasy, "Grafika komputerowa", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
- /* wybór rozmiaru i usytuowania okna pozostawiamy systemowi MS Windows */
- ShowWindow (okno, nCmdShow) ;
- //odswiezamy zawartosc okna
- UpdateWindow (okno) ;
- // GŁÓWNA PĘTLA PROGRAMU
- while (GetMessage(&meldunek, NULL, 0, 0))
- /* pobranie komunikatu z kolejki; funkcja GetMessage zwraca FALSE tylko dla
- komunikatu WM_QUIT; dla wszystkich pozostałych komunikatów zwraca wartość TRUE */
- {
- TranslateMessage(&meldunek); // wstępna obróbka komunikatu
- DispatchMessage(&meldunek); // przekazanie komunikatu właściwemu adresatowi (czyli funkcji obslugujacej odpowiednie okno)
- }
- GdiplusShutdown(gdiplusToken);
- return (int)meldunek.wParam;
- }
- /********************************************************************
- FUNKCJA OKNA realizujaca przetwarzanie meldunków kierowanych do okna aplikacji*/
- LRESULT CALLBACK WndProc (HWND okno, UINT kod_meldunku, WPARAM wParam, LPARAM lParam)
- {
- HMENU mPlik, mInfo, mGlowne;
- /* PONIŻSZA INSTRUKCJA DEFINIUJE REAKCJE APLIKACJI NA POSZCZEGÓLNE MELDUNKI */
- switch (kod_meldunku)
- {
- case WM_CREATE: //meldunek wysyłany w momencie tworzenia okna
- mPlik = CreateMenu();
- AppendMenu(mPlik, MF_STRING, 100, "&Zapiszcz...");
- AppendMenu(mPlik, MF_SEPARATOR, 0, "");
- AppendMenu(mPlik, MF_STRING, 101, "&Koniec");
- mInfo = CreateMenu();
- AppendMenu(mInfo, MF_STRING, 200, "&Autor...");
- mGlowne = CreateMenu();
- AppendMenu(mGlowne, MF_POPUP, (UINT_PTR) mPlik, "&Plik");
- AppendMenu(mGlowne, MF_POPUP, (UINT_PTR) mInfo, "&Informacja");
- SetMenu(okno, mGlowne);
- DrawMenuBar(okno);
- case WM_COMMAND: //reakcje na wybór opcji z menu
- switch (wParam)
- {
- case 100: if(MessageBox(okno, "Zapiszczeć?", "Pisk", MB_YESNO) == IDYES)
- MessageBeep(0);
- break;
- case 101: DestroyWindow(okno); //wysylamy meldunek WM_DESTROY
- break;
- case 200: MessageBox(okno, "Imię i nazwisko:\nNumer indeksu: ", "Autor", MB_OK);
- }
- return 0;
- case WM_LBUTTONDOWN: //reakcja na lewy przycisk myszki
- {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- for (int i = 0; i < 13; i++)
- {
- if ((x >= bezier[i].x - elScale && x <= bezier[i].x + elScale) && (y >= bezier[i].y - elScale && y <= bezier[i].y + elScale))
- {
- vertex = i;
- break;
- }
- drag = true;
- }
- return 0;
- }
- case WM_RBUTTONDOWN:
- {
- closed = false;
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
- if (!initialized)
- {
- initialized = true;
- krzywa.push_back(Point(x, y));
- krzywa.push_back(Point(x, y));
- }
- else
- krzywa.push_back(Point(x, y));
- dragDraw = true;
- return 0L;
- }
- case WM_RBUTTONDBLCLK:
- {
- closed = true;
- krzywa.pop_back();
- InvalidateRect(okno, NULL, true);
- return 0;
- }
- case WM_RBUTTONUP:
- {
- dragDraw = false;
- InvalidateRect(okno, NULL, true);
- return 0;
- }
- case WM_LBUTTONUP:
- {
- if (drag)
- {
- drag = FALSE;
- vertex = -1;
- }
- return 0L;
- }
- case WM_MOUSEMOVE:
- {
- if (vertex > -1 && drag)
- {
- bezier[vertex].x = LOWORD(lParam);
- bezier[vertex].y = HIWORD(lParam);
- InvalidateRect(okno, NULL, true);
- //UpdateWindow(okno);
- }
- else if (dragDraw)
- {
- krzywa[krzywa.size() - 1].X = LOWORD(lParam);
- krzywa[krzywa.size() - 1].Y = HIWORD(lParam);
- InvalidateRect(okno, NULL, true);
- }
- return 0L;
- }
- case WM_PAINT:
- {
- PAINTSTRUCT paint;
- HDC kontekst;
- kontekst = BeginPaint(okno, &paint);
- // MIEJSCE NA KOD GDI
- POINT litera1[] = { {200,300},{300,300},{300,250},{250, 250}, {250, 100}, {200,100}, {200, 250,}, {180, 250}, {180, 300}, };
- POINT litera2[] = { {170, 240}, { 300, 190}, { 300, 150}, {170, 200} };
- HBRUSH pedzle[] = { CreateSolidBrush(RGB(68, 138, 252)), CreateSolidBrush(RGB(147, 53, 255)), CreateSolidBrush(RGB(0, 153, 132)),
- CreateSolidBrush(RGB(2, 70, 109)),CreateSolidBrush(RGB(145, 1, 82)) };
- HPEN pioro = CreatePen(PS_SOLID, 5, RGB(0,0,0));
- SelectObject(kontekst, pioro);
- SelectObject(kontekst, pedzle[2]);
- Pie(kontekst, 0, 0, 450, 450, 0, 0, 225, 450);
- SelectObject(kontekst, pedzle[3]);
- Pie(kontekst, 0, 0, 450, 450, 225, 450, 450, 0);
- SelectObject(kontekst, pedzle[4]);
- Pie(kontekst, 0, 0, 450, 450, 450, 0, 0, 0);
- //MoveToEx(kontekst, 100, 300, NULL);
- //LineTo(kontekst, 800, 300);
- SelectObject(kontekst, pedzle[1]);
- Polygon(kontekst, litera1, 9);
- SelectObject(kontekst, pedzle[0]);
- Polygon(kontekst, litera2, 4);
- PolyBezier(kontekst, bezier, 13);
- for (int i = 0; i < 13; i++)
- {
- Ellipse(kontekst, bezier[i].x - elScale, bezier[i].y - elScale, bezier[i].x + elScale, bezier[i].y + elScale);
- }
- DeleteObject(pioro);
- // utworzenie obiektu umożliwiającego rysowanie przy użyciu GDI+
- // (od tego momentu nie można używać funkcji GDI
- Graphics grafika(kontekst);
- Pen fioletowy(Color(145, 1, 82), 3);
- // MIEJSCE NA KOD GDI+
- if (krzywa.size() && !closed)
- grafika.DrawCurve(&fioletowy, &krzywa[0], krzywa.size());
- else if(krzywa.size() && closed)
- grafika.DrawClosedCurve(&fioletowy, &krzywa[0], krzywa.size());
- // utworzenie czcionki i wypisanie tekstu na ekranie
- FontFamily fontFamily(L"Times New Roman");
- Font font(&fontFamily, 24, FontStyleRegular, UnitPixel);
- PointF pointF(100.0f, 400.0f);
- SolidBrush solidBrush(Color(255, 0, 0, 255));
- //grafika.DrawString(L"To jest tekst napisany za pomocą GDI+.", -1, &font, pointF, &solidBrush);
- EndPaint(okno, &paint);
- return 0;
- }
- case WM_DESTROY: //obowiązkowa obsługa meldunku o zamknięciu okna
- PostQuitMessage (0) ;
- return 0;
- default: //standardowa obsługa pozostałych meldunków
- return DefWindowProc(okno, kod_meldunku, wParam, lParam);
- }
- }