/****************************************************************** Grafika komputerowa, środowisko MS Windows - program przykładowy *****************************************************************/ #include #include #include 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 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); } }