View difference between Paste ID: DgYt2KG7 and 2yBhd6H8
SHOW: | | - or go back to the newest paste.
1
#include <windows.h>
2
#include <algorithm>
3
#include <vector>
4
#include <map>
5
#include <string>
6
#include <array>
7
8
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
9
bool createWinClass(HINSTANCE&, TCHAR*);
10
11
using namespace std;
12
13
struct CRectColor
14
{
15
	unsigned int x, y;
16
	COLORREF pcolor;
17
};
18
19
struct CRectShape
20
{
21
	unsigned int x, y, shape;
22
};
23
24
class CPaint 
25
{
26
	public:
27
		CPaint();
28
29
		void drawPallet(const HWND);
30
		void startDraw(const WORD, const WORD);
31
		void endDraw(const HWND, const WORD, const WORD);
32
		void updatePosition(const RECT);
33
		bool palletArea(const WORD) const;
34
		void userClick(const HWND, const WORD, const WORD, const bool);
35
		unsigned int getXcoord() const;
36
37
		static const unsigned int colors_count = 16;
38
		static const unsigned int rectangle_size = 40;
39
		static const unsigned int pallet_size = 200;
40
41
	private:
42
		void fillPallet();
43
44
		RECT position;
45
		RECT draw_coords;
46
		vector<CRectColor> pallet;
47
		map<string, CRectShape> shapes;
48
		enum shapes { RECTANGLE, CIRCLE, TRIANGLE, TRIANGLE_FILL };
49
50
		unsigned short int current_shape;
51
		COLORREF current_brush_color;
52
		COLORREF current_pen_color;
53
};
54
55
CPaint::CPaint() : current_shape(RECTANGLE), current_brush_color(RGB(0, 0,0)), current_pen_color(RGB(0, 0,0))
56
{
57
	fillPallet();
58
}
59
60
void CPaint::fillPallet() 
61
{
62
	array<COLORREF, colors_count> tab = {
63
		RGB(0, 0, 0), RGB(255, 0, 0), 
64
		RGB(0, 255, 0), RGB(0, 0, 255),
65
		RGB(255, 255, 0), RGB(255, 0, 255), 
66
		RGB(0, 255, 255), RGB(255, 255, 255),
67
		RGB(80, 80, 80), RGB(180, 20, 20), 
68
		RGB(20, 180, 20), RGB(20, 20, 180),
69
		RGB(180, 180, 20), RGB(180, 20, 180), 
70
		RGB(20, 180, 180), RGB(150, 150, 150)
71
	};
72
	for(array<COLORREF, colors_count>::iterator it = tab.begin(); it != tab.end(); it++)
73
	{
74
		CRectColor CRectColor;
75
		CRectColor.x = CRectColor.y = 0;
76
		CRectColor.pcolor = *it;
77
		this->pallet.push_back(CRectColor);
78
	}
79
80
	// shapes
81
	CRectShape defaultrect;
82
	defaultrect.x = defaultrect.y = 0;
83
	defaultrect.shape = RECTANGLE;
84
85
	shapes["rectangle"] = defaultrect;
86
	shapes["circle"] = defaultrect;
87
	shapes["triangle"] = defaultrect;
88
	shapes["trianglefill"] = defaultrect;
89
90
	shapes["circle"].shape = CIRCLE;
91
	shapes["triangle"].shape = TRIANGLE;
92
	shapes["trianglefill"].shape = TRIANGLE_FILL;
93
94
	draw_coords.bottom = draw_coords.left = draw_coords.top = draw_coords.right = 0;
95
}
96
97
void CPaint::updatePosition(const RECT position)
98
{
99
	this->position = position;
100
}
101
102
void CPaint::drawPallet(const HWND hwnd) 
103
{
104
	PAINTSTRUCT paintdata;
105
	HDC hdc = BeginPaint(hwnd, &paintdata);
106
107
	HPEN emptyPen = (HPEN) SelectObject(hdc, GetStockObject(NULL_PEN));
108
	HBRUSH emptyBrush = (HBRUSH) SelectObject(hdc, GetStockObject(NULL_BRUSH));
109
110
	HPEN standardPen = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
111
	HPEN bluePen = CreatePen(PS_SOLID, 0, RGB(0, 0, 255));
112
	HPEN greyPen = CreatePen(PS_SOLID, 0, RGB(180, 180, 180));
113
114
	HBRUSH standardBrush = CreateSolidBrush(RGB(0, 0, 0));
115
	HBRUSH whiteBrush = CreateSolidBrush(RGB(255, 255, 255));
116
	HBRUSH greyBrush = CreateSolidBrush(RGB(180, 180, 180));
117
118
	SelectObject(hdc, greyBrush);
119
	SelectObject(hdc, bluePen);
120
121
	//draw grey palet
122
	Rectangle(hdc, position.right - CPaint::pallet_size, 
123
		0, position.right, position.bottom);
124
	
125
	//draw colors palet
126
	unsigned int i = 0, inc = 0;
127
	unsigned int margin_left = 45;
128
	unsigned int margin_top = 40;
129
130
	SelectObject(hdc, greyPen);
131
	for(vector<CRectColor>::iterator it = pallet.begin(); it != pallet.end(); it++, i++, inc++)
132
	{
133
		if(inc == 8) {
134
			margin_left += CPaint::rectangle_size + 25;
135
			i = 0;
136
		}
137
138
		unsigned int margin = i * (CPaint::rectangle_size + 5);
139
		(*it).x = position.right - CPaint::pallet_size + margin_left;
140
		(*it).y = position.top + margin_top + margin;
141
142
		HBRUSH rectBrush = CreateSolidBrush((*it).pcolor);
143
		SelectObject(hdc, rectBrush);
144
		Rectangle(hdc, (*it).x, (*it).y, 
145
			(*it).x + CPaint::rectangle_size, (*it).y + CPaint::rectangle_size);
146
		DeleteObject(rectBrush);
147
	}
148
149
	//draw shapes pallet
150
	SelectObject(hdc, standardPen);
151
	SelectObject(hdc, whiteBrush);
152
	
153
	unsigned int margin_bottom = 80;
154
	margin_left = 45;
155
156
	//rectangle
157
	shapes["rectangle"].x = position.right - CPaint::pallet_size + margin_left;
158
	shapes["rectangle"].y = position.bottom - margin_bottom - CPaint::rectangle_size;
159
160
	Rectangle(hdc, shapes["rectangle"].x, shapes["rectangle"].y, 
161
			shapes["rectangle"].x + CPaint::rectangle_size, shapes["rectangle"].y + CPaint::rectangle_size);
162
163
	SelectObject(hdc, standardBrush);
164
	Rectangle(hdc, shapes["rectangle"].x + 5, shapes["rectangle"].y + 5, 
165
			shapes["rectangle"].x + CPaint::rectangle_size - 5, shapes["rectangle"].y + CPaint::rectangle_size - 5);
166
167
	//circle
168
	SelectObject(hdc, whiteBrush);
169
	shapes["circle"].x = shapes["rectangle"].x;
170
	shapes["circle"].y = position.bottom - margin_bottom + 5;
171
172
	Rectangle(hdc, shapes["circle"].x, shapes["circle"].y, 
173
			shapes["circle"].x + CPaint::rectangle_size, shapes["circle"].y + CPaint::rectangle_size);
174
175
	SelectObject(hdc, standardBrush);
176
	Ellipse(hdc, shapes["circle"].x + 5, shapes["circle"].y + 5, 
177
			shapes["circle"].x + CPaint::rectangle_size - 5, shapes["circle"].y + CPaint::rectangle_size - 5);
178
179
	//triangle
180
	SelectObject(hdc, whiteBrush);
181
	shapes["triangle"].x = shapes["rectangle"].x + CPaint::rectangle_size + 25;
182
	shapes["triangle"].y = shapes["rectangle"].y;
183
184
	Rectangle(hdc, shapes["triangle"].x, shapes["triangle"].y, 
185
			shapes["triangle"].x + CPaint::rectangle_size, shapes["triangle"].y + CPaint::rectangle_size);
186
187
	POINT trianglePos[3];
188
	trianglePos[0].x = shapes["triangle"].x + 5;
189
	trianglePos[1].x = shapes["triangle"].x + CPaint::rectangle_size - 5;
190
	trianglePos[0].y = trianglePos[1].y = shapes["triangle"].y + 5;
191
	trianglePos[2].y = shapes["triangle"].y + CPaint::rectangle_size - 5;
192
	trianglePos[2].x = (trianglePos[0].x + trianglePos[1].x) / 2;
193
194
	Polygon(hdc, trianglePos, 3);
195
196
	//triangle fill
197
	SelectObject(hdc, whiteBrush);
198
	shapes["trianglefill"].x = shapes["triangle"].x;
199
	shapes["trianglefill"].y = shapes["circle"].y;
200
201
	Rectangle(hdc, shapes["trianglefill"].x, shapes["trianglefill"].y, 
202
			shapes["trianglefill"].x + CPaint::rectangle_size, shapes["trianglefill"].y + CPaint::rectangle_size);
203
204
	SelectObject(hdc, standardBrush);
205
	trianglePos[0].x = shapes["trianglefill"].x + 5;
206
	trianglePos[1].x = shapes["trianglefill"].x + CPaint::rectangle_size - 5;
207
	trianglePos[0].y = trianglePos[1].y = shapes["trianglefill"].y + 5;
208
	trianglePos[2].y = shapes["trianglefill"].y + CPaint::rectangle_size - 5;
209
	trianglePos[2].x = (trianglePos[0].x + trianglePos[1].x) / 2;
210
211
	Polygon(hdc, trianglePos, 3);
212
213
	SelectObject(hdc, emptyPen);
214
	SelectObject(hdc, emptyBrush);
215
	EndPaint(hwnd, &paintdata);
216
217
	DeleteObject(standardPen);
218
	DeleteObject(bluePen);
219
	DeleteObject(greyPen);
220
	DeleteObject(standardBrush);
221
	DeleteObject(whiteBrush);
222
	DeleteObject(greyBrush);
223
}
224
225
unsigned int CPaint::getXcoord() const
226
{
227
	return position.right;
228
}
229
230
void CPaint::startDraw(const WORD x, const WORD y)
231
{
232
	// start draw on client area, remember points
233
	draw_coords.left = x;
234
	draw_coords.top = y;
235
}
236
237
void CPaint::endDraw(const HWND hwnd, const WORD x, const WORD y)
238
{
239
	// end draw on client area
240
	draw_coords.right = x;
241
	draw_coords.bottom = y;
242
243
	HDC hdc = GetDC(hwnd);
244
	HPEN emptyPen = (HPEN) SelectObject(hdc, GetStockObject(NULL_PEN));
245
	HBRUSH emptyBrush = (HBRUSH) SelectObject(hdc, GetStockObject(NULL_BRUSH));
246
247
	HPEN userPen = CreatePen(PS_SOLID, 0, current_pen_color);
248
	HBRUSH userBrush = CreateSolidBrush(current_brush_color);
249
250
	SelectObject(hdc, userPen);
251
	SelectObject(hdc, userBrush);
252
	switch(current_shape)
253
	{
254
		case RECTANGLE:
255
			Rectangle(hdc, draw_coords.left, draw_coords.top, 
256
				draw_coords.right, draw_coords.bottom);
257
			break;
258
		case CIRCLE:
259
			Ellipse(hdc, draw_coords.left, draw_coords.top, 
260
				draw_coords.right, draw_coords.bottom);
261
			break;
262
		case TRIANGLE:
263
		{
264
			POINT trianglePos[4];
265
			trianglePos[0].x = draw_coords.left;
266
			trianglePos[1].x = draw_coords.right;
267
			trianglePos[0].y = trianglePos[1].y = draw_coords.top;
268
			trianglePos[2].y = draw_coords.bottom;
269
			trianglePos[2].x = (trianglePos[0].x + trianglePos[1].x) / 2;
270
			trianglePos[3] = trianglePos[0];
271
			Polyline(hdc, trianglePos, 4);
272
			break;
273
		}
274
		case TRIANGLE_FILL:
275
		{
276
			POINT trianglePos[3];
277
			trianglePos[0].x = draw_coords.left;
278
			trianglePos[1].x = draw_coords.right;
279
			trianglePos[0].y = trianglePos[1].y = draw_coords.top;
280
			trianglePos[2].y = draw_coords.bottom;
281
			trianglePos[2].x = (trianglePos[0].x + trianglePos[1].x) / 2;
282
			Polygon(hdc, trianglePos, 3);
283
			break;
284
		}
285
	}
286
	SelectObject(hdc, emptyPen);
287
	SelectObject(hdc, emptyBrush);
288
	DeleteObject(userPen);
289
	DeleteObject(userBrush);
290
	ReleaseDC(hwnd, hdc);
291
}
292
293
bool CPaint::palletArea(const WORD x) const
294
{
295
	if(x < position.right - pallet_size) // no on grey pallet
296
		return false;
297
298
	return true;
299
}
300
301
void CPaint::userClick(const HWND hwnd, const WORD x, const WORD y, const bool left) 
302
{
303
	if(left) // LPM click
304
	{
305
		// color change?
306
		for(vector<CRectColor>::iterator it = pallet.begin(); it != pallet.end(); it++)
307
		{
308
			if(x >= (*it).x && x <= (*it).x + CPaint::rectangle_size)
309
			{
310
				if(y >= (*it).y && y <= (*it).y + CPaint::rectangle_size)
311
				{
312
					HDC con = GetDC(hwnd);
313
					current_brush_color = GetPixel(con, x, y);
314
					ReleaseDC(hwnd, con);
315
					break;
316
				}
317
			}
318
		}
319
320
		// shape change?
321
		unsigned int i = 0;
322
		for(map<string, CRectShape>::iterator it = shapes.begin(); it != shapes.end(); it++, i++)
323
		{
324
			if(x >= (*it).second.x && x <= (*it).second.x + CPaint::rectangle_size)
325
			{
326
				if(y >= (*it).second.y && y <= (*it).second.y + CPaint::rectangle_size)
327
				{
328
					current_shape = (*it).second.shape;
329
					break;
330
				}
331
			}
332
		}
333
	}
334
	else // RPM click
335
	{
336
		// color change?
337
		for(vector<CRectColor>::iterator it = pallet.begin(); it != pallet.end(); it++)
338
		{
339
			if(x >= (*it).x && x <= (*it).x + CPaint::rectangle_size)
340
			{
341
				if(y >= (*it).y && y <= (*it).y + CPaint::rectangle_size)
342
				{
343
					HDC con = GetDC(hwnd);
344
					current_pen_color = GetPixel(con, x, y);
345
					ReleaseDC(hwnd, con);
346
					break;
347
				}
348
			}
349
		}
350
	}
351
}
352
// END CLASS
353
354
TCHAR APPName[] = TEXT("Paint application");
355
TCHAR ClassName[] = TEXT("Class name");
356
357
CPaint Paint;
358
359
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPevInstance, LPSTR lpCmdLine, int nShowCmd)
360
{
361
	if(!createWinClass(hInstance, ClassName)) 
362
		return 1;
363
364
	HWND window = CreateWindowEx(0, ClassName, APPName, WS_OVERLAPPEDWINDOW, 200, 50, 800, 650, 0, 0, 0, 0);
365
	if(window) 
366
	{
367
		MSG msg;
368
		ShowWindow(window, nShowCmd);
369
370
		while(GetMessage(&msg, 0, 0, 0) > 0)
371
		{
372
			TranslateMessage(&msg);
373
			DispatchMessage(&msg);
374
		}
375
	}
376
	else MessageBox(0, TEXT("Inicjalizacja okna nie powiodła się."), APPName, MB_OK | MB_ICONERROR);
377
	UnregisterClass(ClassName, hInstance);
378
	return 0;
379
}
380
381
static LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
382
{
383
	static bool draw = false;
384
	switch(msg)
385
	{
386
		case WM_CLOSE:
387
		{
388
			if(MessageBox(hwnd, TEXT("Czy na pewno zamknąć aplikację?"), APPName, MB_YESNO) == IDYES)
389
			{
390
				DestroyWindow(hwnd);
391
				break;
392
			}
393
		}
394
		case WM_MOVE:
395
		case WM_SIZE:
396
		{
397
			RECT rectangle;
398
			InvalidateRect(hwnd, 0, true);
399
			GetClientRect(hwnd, &rectangle);
400
			Paint.updatePosition(rectangle);
401
			break;
402
		}
403
		case WM_GETMINMAXINFO:
404
		{
405
			MINMAXINFO* mmi = (MINMAXINFO*)lParam;
406
			mmi->ptMinTrackSize.x = CPaint::pallet_size;
407
			mmi->ptMinTrackSize.y = 580;
408
			return 0;
409
		}
410
		case WM_PAINT:
411
		{
412
			Paint.drawPallet(hwnd);
413
			break;
414
		}
415
		case WM_LBUTTONDOWN: 
416
		{
417
			if(Paint.palletArea(LOWORD(lParam))) 
418
				Paint.userClick(hwnd, LOWORD(lParam), HIWORD(lParam), true); // brush / shape choice
419
			else 
420
			{
421
				draw = true;
422
				Paint.startDraw(LOWORD(lParam), HIWORD(lParam));
423
			}
424
			break;
425
		}
426
		case WM_LBUTTONUP: 
427
		{
428
			if(!Paint.palletArea(LOWORD(lParam)) && draw) // end draw
429
				Paint.endDraw(hwnd, LOWORD(lParam), HIWORD(lParam));
430
431
			draw = false;
432
			break;
433
		}
434
		case WM_RBUTTONDOWN: 
435
		{
436
			if(Paint.palletArea(LOWORD(lParam))) // pen color choice
437
				Paint.userClick(hwnd, LOWORD(lParam), HIWORD(lParam), false);
438
			break;
439
		}
440
		case WM_DESTROY:
441
			PostQuitMessage(0);
442
			break;
443
		default:
444
			return DefWindowProc(hwnd, msg, wParam, lParam); 
445
	}
446
	return 0;
447
}
448
449
static bool createWinClass(HINSTANCE& hInstance, TCHAR* ClassName)
450
{
451
	WNDCLASSEX wc;
452
	wc.cbClsExtra = wc.cbWndExtra = 0;
453
	wc.cbSize = sizeof(WNDCLASSEX);
454
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
455
	wc.hCursor = LoadCursor(0, IDC_ARROW);
456
	wc.hIconSm = wc.hIcon = LoadIcon(0, IDI_APPLICATION);
457
	wc.hInstance = hInstance;
458
	wc.lpfnWndProc = WinProc;
459
	wc.lpszClassName = ClassName;
460
	wc.lpszMenuName = 0;
461
	wc.style = 0;
462
	return (RegisterClassEx(&wc) != 0);
463
}