// API.cpp :    
//

#include "stdafx.h"
#include "API.h"
#define MAX_LOADSTRING 100

//========  :
HINSTANCE hInst;						//  
TCHAR szTitle[MAX_LOADSTRING];		//   
TCHAR szWindowClass[MAX_LOADSTRING];	//  

//========  ,    
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
							HINSTANCE hPrevInstance,
							LPSTR lpCmdLine,
							int nCmdShow)
{
	//======= TODO:   
	MSG msg;
	HACCEL hAccelTable;

	//=======    
	LoadString(hInstance, IDS_APP_TITLE, szTitle,
											MAX_LOADSTRING);
	LoadString(hInstance, IDC_API, szWindowClass,
											MAX_LOADSTRING);

	//=======    
	MyRegisterClass(hInstance);

	//=======  :
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	//=======   
	hAccelTable = LoadAccelerators(hInstance,
										(LPCTSTR)IDC_API);

	//=======     :
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable,
										&msg)) 
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  :   
//
//  COMMENTS:
//
//       ,   
//   Win32 ,    
//  'RegisterClassEx',   Windows 95.
//  'RegisterClassEx'   
//   (small) , 
//  .
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc		= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance,
								(LPCTSTR)IDI_API);
	wcex.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_API;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm	= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
										 
	return RegisterClassEx(&wcex);
}

//
//		FUNCTION: InitInstance(HANDLE, int)
//
// :    
//     
//
//   COMMENTS:
//
//       
//       
//  .
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;

	//=======   
	hInst = hInstance;
	//=======   
	hWnd = CreateWindow(szWindowClass, szTitle,
			WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,
			0, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  :    .
//
//  WM_COMMAND	-   
//  WM_PAINT	-  
//  WM_DESTROY	-      
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
								WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		//======    :
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst,(LPCTSTR)IDD_ABOUTBOX,hWnd,
						(DLGPROC)About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam,
									lParam);
		}
		break;
	//=======    
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		//======= TODO:    
		EndPaint(hWnd, &ps);
		break;
	//=======   
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

//=======     About
LRESULT CALLBACK About(HWND hDlg, UINT message,
								WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	//=======    
	case WM_INITDIALOG:
		return TRUE;

	//=======   , 
	//=======    
	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || 
			LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
		}
		break;
	}
	return FALSE;
}


	//=====      
	CHOOSECOLOR cc;
	//=====     
	static COLORREF color = RGB(255,0,0);
	//=====  ,  
	static COLORREF CustColors[16];


	#include <string>
	using namespace std;


	//       IDM_COLOR
	case ID_EDIT_COLOR:
		//       
		ZeroMemory(&cc, sizeof(CHOOSECOLOR));

		//======  
		cc.lStructSize = sizeof(CHOOSECOLOR);
		//======     
		cc.lpCustColors = (LPDWORD)CustColors;
	
		if (ChooseColor(&cc))	//  
		{							//     OK,
			//    
			color = cc.rgbResult;
			//   
			//   
			InvalidateRect(hWnd,NULL,TRUE);
		}
		break;


	//====== x-:
	static int iXCenter;	//  ,
	static int iXPos;		//  
 static int iXMax;		//  

	int iYPos = 0;			//  y- 
	int nLines;				//  
	SIZE szText;		//    

	//======   Windows
	static DWORD dwPenStyle[] = 
	{
		PS_NULL, PS_SOLID, PS_DOT, PS_DASH,
		PS_DASHDOT, PS_DASHDOTDOT
	};

//======      
	static string style[] = 
	{
		"PS_NULL","PS_SOLID","PS_DOT","PS_DASH",
		"PS_DASHDOT","PS_DASHDOTDOT"
	};

	string sText;		//   

	//=====   -     
	LOGBRUSH lb = { BS_SOLID, color, 0 };


	case WM_SIZE:
		//====  lParam   .
		//====     
		iXMax = LOWORD(lParam) - 50;
		iXCenter = LOWORD(lParam)/2;
		break;

	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		//=====    (. MSDN)
		SetTextAlign(hdc, TA_NOUPDATECP |
						TA_LEFT | TA_BASELINE);
		sText = "   Win32  (Cosmetic pen)";

		//==      
		GetTextExtentPoint(hdc,sText.c_str(),
							sText.size(),&szText);

		//=====     
		iYPos += szText.cy;
		iXPos = iXCenter - szText.cx/2;
		//====  
		TextOut(hdc,iXPos, iYPos, sText.c_str(),
				sText.size());

		//====    
		nLines = sizeof(style)/sizeof(style[0]);
		for (int i = 0; i < nLines; i++)
		{
			//=====    
			DWORD dw = PS_COSMETIC | dwPenStyle[i];
			//=====     
			//=====    1 
			HPEN hp = ExtCreatePen(dw, 1, &lb, 0,NULL);
			//=====     
			HPEN hOld = (HPEN)SelectObject(hdc,hp);
			iYPos += szText.cy;			//  
			//=====     (10, iYPos)
			MoveToEx(hdc, 10, iYPos, NULL);
			//====     (iXMax, iYPos)
			LineTo(hdc, iXMax, iYPos);
			//===      
			SelectObject(hdc, hOld);
			//===   
			DeleteObject(hp);
			//===   
			TextOut(hdc, 10, iYPos, style[i].c_str(),
						style[i].size());
		}

		EndPaint(hWnd, &ps);
		break;


//=======   (alternate - solid)
		lb.lbStyle = BS_SOLID;
		sText = "  alternate  solid";
		GetTextExtentPoint(hdc,sText.c_str(),
								sText.size(),&szText);

		iYPos += 2 * szText.cy;
		iXPos = iXCenter - szText.cx/2;
		TextOut(hdc, iXPos, iYPos,
						sText.c_str(), sText.size());

		for (i = 0; i < 2; i++) 
		{
			DWORD dw = i ? PS_COSMETIC
							: PS_COSMETIC | PS_ALTERNATE;
			HPEN hp = ExtCreatePen(dw, 1, &lb, 0, NULL);
			HPEN hOld = (HPEN)SelectObject(hdc, hp);
			iYPos += szText.cy;
			MoveToEx(hdc, 10, iYPos, NULL);
			LineTo(hdc, iXMax,iYPos);
			SelectObject(hdc, hOld);
			DeleteObject(hp);
			TextOut(hdc, 10, iYPos, alt[i].c_str(),
								alt[i].size());
		}


	//======   (hatch) ,  
	//======    
	static UINT uHatch[] =
	{
		HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS,
		HS_FDIAGONAL, HS_HORIZONTAL, HS_VERTICAL
	};
	//=====    
	static string brush[] =
	{
		"HS_BDIAGONAL", "HS_CROSS", "HS_DIAGCROSS",
		"HS_FDIAGONAL", "HS_HORIZONTAL", "HS_VERTICAL"
	};


LineTo(hdc, iXMax, iYPos + 3);


//========  
		lb.lbStyle = BS_HATCHED;		//  
		sText = "    (Geometric pen)";
		GetTextExtentPoint(hdc,sText.c_str(),
								sText.size(),&szText);
		iYPos += 2 * szText.cy;		//   
		iXPos = iXCenter - szText.cx/2;
		TextOut(hdc, iXPos, iYPos,
								sText.c_str(), sText.size());
		nLines = sizeof(brush)/sizeof(brush[0]);

		for (i = 0; i < nLines; i++)
		{
			//=======    
			lb.lbHatch = uHatch[i];
			//==       5 
			HPEN hp = ExtCreatePen(PS_GEOMETRIC, 5, &lb,0,0);
			HPEN hOld = (HPEN)SelectObject(hdc, hp);
			iYPos += szText.cy;
			MoveToEx(hdc, 10, iYPos, NULL);
			LineTo(hdc, iXMax,iYPos);
			SelectObject(hdc, hOld);
			DeleteObject(hp);
			TextOut(hdc, 10, iYPos, brush[i].c_str(),
						brush[i].size());
		}


	//=======    
	static DWORD dwUser[3][4] =
	{
		{8,3,3,3},
		{3,3,3,3},
		{15, 4, 3, 4}
	};



//=======   (user-defined)
		lb.lbStyle = BS_SOLID;

		sText = "    (Geometric pen)";
		GetTextExtentPoint(hdc,sText.c_str(),
								sText.size(),&szText);
		iYPos += 2 * szText.cy;
		iXPos = iXCenter - szText.cx/2;
		TextOut(hdc, iXPos, iYPos,
							sText.c_str(), sText.size());
		nLines = sizeof(dwUser)/sizeof(dwUser[0]);
		//======   
		//====== (  dwUser)
		for (i = 0; i < nLines; i++)
		{
			DWORD dw = PS_GEOMETRIC | PS_USERSTYLE
						| PS_ENDCAP_FLAT;
			HPEN hp = ExtCreatePen(dw, i+2, &lb, 4, dwUser[i]);
			HPEN hOld = (HPEN)SelectObject(hdc, hp);
			iYPos += szText.cy;
			MoveToEx(hdc, 10, iYPos, NULL);
			LineTo(hdc, iXMax,iYPos);
			SelectObject(hdc, hOld);
			DeleteObject(hp);
			TextOut(hdc, 10, iYPos,
							user[i].c_str(), user[i].size());
		}


	//=======   bitmap
	static UINT nPatterns[] =
	{
		IDB_PAT1, IDB_PAT2, IDB_PAT3
	};
	static string bitmap[] =
	{
		"BS_PATTERN, 1", "BS_PATTERN, 2", "BS_PATTERN, 3"
	};


	//=======   (bitmap)
	lb.lbStyle = BS_PATTERN;
	sText = "   bitmap- (Geometric pen)";
	GetTextExtentPoint(hdc,sText.c_str(),
							sText.size(),&szText);
	iYPos += 2 * szText.cy;
	iXPos = iXCenter - szText.cx/2;
	TextOut(hdc, iXPos, iYPos, sText.c_str(), sText.size());
	nLines = sizeof(nPatterns)/sizeof(nPatterns[0]);

	for (i = 0; i < nLines; i++) 
	{
		HBITMAP hBmp;
		hBmp = LoadBitmap(GetModuleHandle(NULL),
									(char*)nPatterns[i]);
		lb.lbHatch = long(hBmp);
		HPEN hp = ExtCreatePen(PS_GEOMETRIC, 5, &lb, 0, 0);
		HPEN hOld = (HPEN)SelectObject(hdc, hp);
		iYPos += szText.cy;
		MoveToEx(hdc, 10, iYPos, NULL);
		LineTo(hdc, iXMax,iYPos);
		SelectObject(hdc, hOld);
		DeleteObject(hp);
		TextOut(hdc, 10, iYPos, bitmap[i].c_str(),
					bitmap[i].size());
	}



