#include <windows.h>

// deklaracja zapowiadająca
LRESULT CALLBACK WindowProc(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,  
                    LPSTR lpCmdLine, int nCmdShow )
{
	// Krok 1: rejestracja klasy okien
	char NazwaKlasy [] = "Zbyszek";
	WNDCLASSEX wc = {0};
	wc.cbSize = sizeof(wc);
	wc.style = CS_HREDRAW | CS_VREDRAW;		// styl okna
	wc.lpfnWndProc = WindowProc;			// adres procedury okien
	wc.hInstance =  hInstance;              // uchwyt egzemplarza programu
	wc.lpszClassName = NazwaKlasy;          // nazwa klasy okien
	wc.hCursor = LoadCursor(0, IDC_ARROW);  // kursor
	wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); // pedzel tla

	RegisterClassEx(&wc); 

	// Krok 2: utworzenie okna
	HWND hwnd = CreateWindowEx(
		0,                      // dodatkowy styl okna
		NazwaKlasy,             // klasa okien
		"Moje pierwsze okno!",  // nazwa okienka
		WS_OVERLAPPEDWINDOW,    // styl okna
		10, 10, 700, 400,       // polozenie okna (x0, y0, szer, wys)
		0,                      // rodzic lub wlasciciel okna
		0,                      // identyfikator menu lub okna potomnego
		hInstance,              // hInstance z WinMain
		0);                     // dane "dodatkowe"

	// jesli uchwyt jest niewazny...
	if (hwnd == 0)
	{
		::MessageBox(0, "Funkcja CreateWindowEx nie zadziałała!", 
			       "uwaga", MB_ICONSTOP);
		return 0;
	}

	// Krok 3: wyswietlenie okna
	ShowWindow(hwnd, SW_SHOW);
	
	// Krok 4: utworzenie petli komunikatow
    MSG msg;
	while(::GetMessage(&msg, 0, 0, 0))
	{
		::TranslateMessage(&msg);
		::DispatchMessage(&msg);
	}
	return msg.wParam;
}


// procedura okna obsluguje komunikaty zwiazane z naszym(i) oknem(oknami)
LRESULT CALLBACK WindowProc(HWND hwnd,  UINT uMsg, 
							WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
		// Ten komunikat nakazuje odrysowac zawartosc okna!
	case WM_PAINT:
		{
			static int ile_razy = 0;
			ile_razy++;

			PAINTSTRUCT ps;
			HDC hdc = ::BeginPaint(hwnd, &ps);
			
			HPEN moje_pioro = ::CreatePen(PS_SOLID, 3, RGB(255,0,0) );
			HPEN stare_pioro = (HPEN)::SelectObject(hdc, moje_pioro);

			HBRUSH moj_pedzel = ::CreateSolidBrush(RGB(255,255,0));
			HBRUSH stary_pedzel = (HBRUSH)::SelectObject(hdc, moj_pedzel);

			HFONT nowa_czcionka = ::CreateFont(
				50, // rozmiar czcionki
				0, 
				3400, // 10 * kat nachylenia napisu w stopniach
				0, FW_NORMAL, 0, 0,
				0, 
				EASTEUROPE_CHARSET, // zestaw snaków dla Europy Wschodniej
				OUT_DEFAULT_PRECIS,
				CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
				FF_SCRIPT, // czcionka naśladująca pismo odreczne
				0 );
			HFONT stary_font = (HFONT)::SelectObject(hdc, nowa_czcionka);
			
			::SetTextColor(hdc, RGB(0, 128, 0));
			::SetBkColor(hdc, RGB(255,255,220));

			char bufor[256];
			::wsprintf(bufor, "komunikat WM_PAINT obsłużono %d raz(y)", ile_razy);

			::TextOut(hdc, 100, 100, bufor, strlen(bufor));
			::Ellipse(hdc, 10, 10, 100, 100);
						
			::SelectObject(hdc, stare_pioro);
			::SelectObject(hdc, stary_pedzel);
			::SelectObject(hdc, stary_font);

			::DeleteObject(moje_pioro);
			::DeleteObject(moj_pedzel);
			::DeleteObject(stary_font);

			::EndPaint(hwnd, &ps);
			return 1;
			break;
		}
	// Ten komunikat informuje, ze nasze okno wlasnie 
	// nieodracalnie zniknelo z ekranu!
	case WM_DESTROY:
		// Ponizsza funkcja przerwie petle komunikatow w WinMain, a wiec 
		// zakonczy program
		
		::PostQuitMessage(0);
		return 0;
	// nieobsluzone komunikaty odsylamy do DefWindowProc
	default: return ::DefWindowProc (hwnd, uMsg, wParam, lParam);
	}
}
