
#include <windows.h>
#include <wchar.h>
//#include <stdlib.h>

#define JMENOTRIDYOKNAAPLIKACE "MojeAplikace"

#define TLACITKO1 1
#define TLACITKO2 2
#define EDITBOX1 3
#define EDITBOX2 4


LRESULT WINAPI HlavniProceduraOkna(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance		// ukazatel na instanci nasi aplikace
			, HINSTANCE hPrevInstance	// ukazatel na instanci predchozi aplikace (vzdy NULL)
			, LPSTR lpCmdLine	// retezec prikazoveho radku (char *)
			, int nCmdShow)		// informace jak se ma okno zobrazit (minimalizovane, maximalizovane...)
{
	HWND oknoAplikace;
	// vyplneni a zaregistrovani tridy okna
	WNDCLASS tridaOkna;
	tridaOkna.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; // vlastni kontext zarizeni(platno), prekreslit okno pri pohybu ci zmene velikosti horizontalne ci vertikalne
	tridaOkna.lpfnWndProc = HlavniProceduraOkna;	// ukazatel na proceduru hlavniho okna aplikace
	tridaOkna.cbClsExtra = 0;	// extra bytu navic k pameti pro tridu okna
	tridaOkna.cbWndExtra = 0;	// extra bytu navic k pameti vyhrazene pro okno vytvorene z teto tridy
	tridaOkna.hInstance = hInstance;	// ukazatel na aplikaci vlastnici proceduru okna, na niz jsme dali ukazatel vyse
	tridaOkna.hIcon = NULL;	// LoadIcon(NULL, IDI_APPLICATION);	// NULL znamena defaultni ikonu od operacniho systemu
	tridaOkna.hCursor = LoadCursor(NULL, IDC_ARROW);	// kurzor, ktery se bude zobrazovat nad oknem vytvorenym z teto tridy
	tridaOkna.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);	// barva pozadi okna
	tridaOkna.lpszMenuName = NULL;	// zadne menu
	tridaOkna.lpszClassName = JMENOTRIDYOKNAAPLIKACE;	// jmeno tridy okna
	if (RegisterClass(&tridaOkna)==0) // pokud se nepovedla zaregistrovat trida okna
	{
		MessageBox(NULL, "Nepovedlo se zaregistrovat tridu okna", "Varovani", MB_OK | MB_ICONERROR);
		return 0;
	}
	// vytvorime hlavni okno aplikace
	oknoAplikace = CreateWindow(JMENOTRIDYOKNAAPLIKACE	// jmeno tridy okna, podle niz se ma okno vytvorit
		, "Nase okno aplikace"	// titulek okna (jmeno okna)
		, WS_OVERLAPPEDWINDOW | WS_HSCROLL // okno s titulkovym pruhem, systemovym menu, pozadim, minimize a maximizeboxy, ...
		, 100	// x pozice, necha se pouzit CW_USEDEFAULT pro umisteni windowsi
		, 300	// y pozice
		, 500	// sirka okna
		, 300	// vyska okna
		, NULL	// ukazatel na rodicovske okno
		, NULL	// ukazatel na menu  - zadne menu nemame
		, hInstance	// ukazatel na instanci aplikace vlastnici toto okno
		, NULL);	// zadne dalsi parametry
	if (oknoAplikace==NULL) // nepodarilo se vytvorit okno aplikace
	{
		MessageBox(NULL, "Nepodarilo se vytvorit hlavni okno aplikace", "Hlaska", MB_OK | MB_ICONERROR);
		return 0;
	}
	ShowWindow(oknoAplikace, nCmdShow);
	// vstoupime do smycky zprav
	MSG msg;
	while (GetMessage(&msg	// adresa struktury msg, do niz se vyplni informace o zprave vyjmute z fronty zprav
		, NULL	// ukazatel na okno nasi aplikace pro nejz zpravy prijmat(NULL znamena vsechna okna nasi aplikace)
		, 0	// jaky typ zpravy jako prvni	(0... vsechny)
		, 0) // jaky typ zpravy jako posledni (0 ... vsechny)
		)
	{
		TranslateMessage(&msg);	// prelozi virtualni klavesy na znaky
		DispatchMessage(&msg);	// distribuuje zpravu prislune procedure okna
	}
	return (int) msg.wParam;
}

LPTSTR GetTextFromEditBox(HWND odkud)	// odkud je hwnd daneho editboxu
{
	WORD pocetZnaku;
	LPTSTR retezec;	// typedef TCHAR* LPCTSTR;
	pocetZnaku = (WORD) SendMessage(odkud,EM_LINELENGTH,0,0); // vrati pocet znaku
	retezec = new TCHAR[pocetZnaku+1];
	retezec[pocetZnaku]=0;
	SendMessage(odkud,EM_GETLINE,0,(LPARAM)retezec);
	return retezec;
}


void Vykresli(HWND hwndKam)
{
	HDC platno, hdcBitmap;
	PAINTSTRUCT ps;
	HPEN starePero;
	HBRUSH staryStetec;
	HBITMAP bitmapa;
	BITMAP infoOBitmape;
	platno = BeginPaint(hwndKam,&ps);	// platno = GetDC(hwndKam);
	if (platno != NULL) {
		starePero = (HPEN) SelectObject(platno, CreatePen(PS_SOLID, 8, RGB(255,0,0)));
		Rectangle(platno, 10,10, 100,80);
		hdcBitmap = CreateCompatibleDC(platno);
		if (hdcBitmap) {
			bitmapa = (HBITMAP) LoadImage(NULL,	// odkud (z jake aplikace)
				"c:\\Windows\\Winnt256.bmp", // jmeno
				IMAGE_BITMAP,	// co (ikona, bitmapa, cursor)
				0,	// sirka - u bitmapy 0
				0,	// vyska - u bitmapy 0
				LR_LOADFROMFILE);
			GetObject(bitmapa, // o jakem objektu
				sizeof(BITMAP),	// pocet bytu na adrese kam se ma ulozit info
				&infoOBitmape);	// adresa kam se ma ulozit info
			SelectObject(hdcBitmap, bitmapa);
			StretchBlt(platno, 300,10,150,200, // kam
				hdcBitmap,0,0,infoOBitmape.bmWidth,infoOBitmape.bmHeight, // odkud
				SRCCOPY);	// jak
			DeleteDC(hdcBitmap);
			DeleteObject(bitmapa);
		}
		DeleteObject(SelectObject(platno, CreatePen(PS_SOLID, 3, RGB(0,0,255))));
		staryStetec = (HBRUSH) SelectObject(platno, CreateSolidBrush(RGB(0,255,0)));
		Ellipse(platno, 10,80,100,150);
		
		DeleteObject(SelectObject(platno, starePero));
		DeleteObject(SelectObject(platno, staryStetec));
		EndPaint(hwndKam, &ps);		// ReleaseDC(hwndKam, platno);
	}
}

void VlozOvladaciPrvky(HWND hwndKam) {
	HINSTANCE hInstance;
	HWND prvek;
	hInstance = (HINSTANCE) GetWindowLong(hwndKam, GWL_HINSTANCE);
	// tlacitko
	prvek = CreateWindow("BUTTON"	// trida z OS pro tlacitko
				, "tlacitko 1"	// popisek tlacitka
				, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON	// styl tlacitka 
				, 200	// x pozice
				, 150	// y pozice
				, 100	// sirka
				, 25	// vyska
				, hwndKam	// rodicovske okno
				, (HMENU) TLACITKO1	// identifikator tlacitka (cislo)
				, hInstance	// aplikace
				, NULL);
	prvek = CreateWindow("BUTTON"	// trida z OS pro tlacitko
				, "zobraz dlg"	// popisek tlacitka
				, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON	// styl tlacitka 
				, 200	// x pozice
				, 200	// y pozice
				, 100	// sirka
				, 25	// vyska
				, hwndKam	// rodicovske okno
				, (HMENU) TLACITKO2	// identifikator tlacitka (cislo)
				, hInstance	// aplikace
				, NULL);
	prvek = CreateWindow("EDIT"	
				, "123"
				, WS_CHILD | WS_VISIBLE | ES_NUMBER | WS_BORDER	// pouze na cisla
				, 200
				, 100
				, 100
				, 25
				, hwndKam
				, (HMENU) EDITBOX1
				, hInstance
				, NULL);
	prvek = CreateWindow("EDIT"	
				, "56"
				, WS_CHILD | WS_VISIBLE |ES_NUMBER|  WS_BORDER	// pouze na cisla
				, 200
				, 50
				, 100
				, 25
				, hwndKam
				, (HMENU) EDITBOX2
				, hInstance
				, NULL);

}

void VypoctiSoucet(HWND hlavniOkno) 
{
	int cislo1, cislo2, vysledek;
	LPTSTR retezec;
	HWND editBox;
	editBox = GetDlgItem(hlavniOkno, EDITBOX1);
	retezec = GetTextFromEditBox(editBox);
	cislo1 = atoi(retezec);
//	MessageBox(hlavniOkno, retezec, "v Editu1", MB_OK |MB_ICONINFORMATION);
	delete[] retezec;
	editBox = GetDlgItem(hlavniOkno, EDITBOX2);
	retezec = GetTextFromEditBox(editBox);
	cislo2 = atoi(retezec);
//	MessageBox(hlavniOkno, retezec, "V Editu 2", MB_OK | MB_ICONINFORMATION);
	delete[] retezec;
	vysledek = cislo1+ cislo2;
	retezec = new TCHAR[20+1];
	retezec = itoa(vysledek,retezec,10);	// 10tkova soustava
	MessageBox(hlavniOkno, retezec, "Soucet je:", MB_OK | MB_ICONINFORMATION);
	delete[] retezec;
}

LRESULT WINAPI HlavniProceduraOkna(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//	LPCTSTR retezec;
	switch(uMsg) {
		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				case EDITBOX1:
					break; 
				case TLACITKO1:
					VypoctiSoucet(hwnd);
					break;
				case TLACITKO2:
					MessageBox(hwnd, "Stisknuto tlacitko 2", "Hlaska",MB_OK | MB_ICONINFORMATION);
					break;
				default:
					return DefWindowProc(hwnd, uMsg, wParam, lParam);
			}
			break;
		case WM_CREATE:
			VlozOvladaciPrvky(hwnd);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);	// posle zpravu WM_QUIT a do parametru wParam da parametr (0)
			break;
		case WM_PAINT:
			// veskere kresleni do okna
			Vykresli(hwnd);
			break;
		default:
			return DefWindowProc(hwnd, uMsg, wParam, lParam);
	}
	return 0;
}
