- Create another branch for networking fixes
[reactos.git] / base / applications / paint / winproc.c
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/paint/winproc.c
5 * PURPOSE: Window procedure of the main window and all children apart from
6 * hPalWin, hToolSettings and hSelection
7 * PROGRAMMERS: Benedikt Freisen
8 */
9
10 /* INCLUDES *********************************************************/
11
12 #include <windows.h>
13 #include <commctrl.h>
14 //#include <htmlhelp.h>
15 #include <stdio.h>
16 #include <tchar.h>
17 #include "definitions.h"
18 #include "globalvar.h"
19 #include "dialogs.h"
20 #include "dib.h"
21 #include "drawing.h"
22 #include "history.h"
23 #include "mouse.h"
24 #include "registry.h"
25
26 /* FUNCTIONS ********************************************************/
27
28 void
29 selectTool(int tool)
30 {
31 ShowWindow(hSelection, SW_HIDE);
32 activeTool = tool;
33 pointSP = 0; // resets the point-buffer of the polygon and bezier functions
34 SendMessage(hToolSettings, WM_PAINT, 0, 0);
35 ShowWindow(hTrackbarZoom, (tool == 6) ? SW_SHOW : SW_HIDE);
36 }
37
38 void
39 updateCanvasAndScrollbars()
40 {
41 ShowWindow(hSelection, SW_HIDE);
42 MoveWindow(hImageArea, 3, 3, imgXRes * zoom / 1000, imgYRes * zoom / 1000, FALSE);
43 InvalidateRect(hScrollbox, NULL, TRUE);
44 InvalidateRect(hImageArea, NULL, FALSE);
45
46 SetScrollPos(hScrollbox, SB_HORZ, 0, TRUE);
47 SetScrollPos(hScrollbox, SB_VERT, 0, TRUE);
48 }
49
50 void
51 zoomTo(int newZoom, int mouseX, int mouseY)
52 {
53 int tbPos = 0;
54 int tempZoom = newZoom;
55
56 long clientRectScrollbox[4];
57 long clientRectImageArea[4];
58 int x, y, w, h;
59 GetClientRect(hScrollbox, (LPRECT) &clientRectScrollbox);
60 GetClientRect(hImageArea, (LPRECT) &clientRectImageArea);
61 w = clientRectImageArea[2] * clientRectScrollbox[2] / (clientRectImageArea[2] * newZoom / zoom);
62 h = clientRectImageArea[3] * clientRectScrollbox[3] / (clientRectImageArea[3] * newZoom / zoom);
63 x = max(0, min(clientRectImageArea[2] - w, mouseX - w / 2)) * newZoom / zoom;
64 y = max(0, min(clientRectImageArea[3] - h, mouseY - h / 2)) * newZoom / zoom;
65
66 zoom = newZoom;
67
68 ShowWindow(hSelection, SW_HIDE);
69 MoveWindow(hImageArea, 3, 3, imgXRes * zoom / 1000, imgYRes * zoom / 1000, FALSE);
70 InvalidateRect(hScrollbox, NULL, TRUE);
71 InvalidateRect(hImageArea, NULL, FALSE);
72
73 SendMessage(hScrollbox, WM_HSCROLL, SB_THUMBPOSITION | (x << 16), 0);
74 SendMessage(hScrollbox, WM_VSCROLL, SB_THUMBPOSITION | (y << 16), 0);
75
76 while (tempZoom > 125)
77 {
78 tbPos++;
79 tempZoom = tempZoom >> 1;
80 }
81 SendMessage(hTrackbarZoom, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) tbPos);
82 }
83
84 void
85 drawZoomFrame(int mouseX, int mouseY)
86 {
87 HDC hdc;
88 HPEN oldPen;
89 HBRUSH oldBrush;
90 LOGBRUSH logbrush;
91 int rop;
92
93 long clientRectScrollbox[4];
94 long clientRectImageArea[4];
95 int x, y, w, h;
96 GetClientRect(hScrollbox, (LPRECT) &clientRectScrollbox);
97 GetClientRect(hImageArea, (LPRECT) &clientRectImageArea);
98 w = clientRectImageArea[2] * clientRectScrollbox[2] / (clientRectImageArea[2] * 2);
99 h = clientRectImageArea[3] * clientRectScrollbox[3] / (clientRectImageArea[3] * 2);
100 x = max(0, min(clientRectImageArea[2] - w, mouseX - w / 2));
101 y = max(0, min(clientRectImageArea[3] - h, mouseY - h / 2));
102
103 hdc = GetDC(hImageArea);
104 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 0, 0));
105 logbrush.lbStyle = BS_HOLLOW;
106 oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
107 rop = SetROP2(hdc, R2_NOT);
108 Rectangle(hdc, x, y, x + w, y + h);
109 SetROP2(hdc, rop);
110 DeleteObject(SelectObject(hdc, oldBrush));
111 DeleteObject(SelectObject(hdc, oldPen));
112 ReleaseDC(hImageArea, hdc);
113 }
114
115 BOOL drawing;
116
117 LRESULT CALLBACK
118 WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
119 {
120 switch (message) /* handle the messages */
121 {
122 case WM_DESTROY:
123 PostQuitMessage(0); /* send a WM_QUIT to the message queue */
124 break;
125
126 case WM_CLOSE:
127 if (hwnd == hwndMiniature)
128 {
129 ShowWindow(hwndMiniature, SW_HIDE);
130 showMiniature = FALSE;
131 break;
132 }
133 if (!imageSaved)
134 {
135 TCHAR programname[20];
136 TCHAR saveprompttext[100];
137 TCHAR temptext[500];
138 LoadString(hProgInstance, IDS_PROGRAMNAME, programname, SIZEOF(programname));
139 LoadString(hProgInstance, IDS_SAVEPROMPTTEXT, saveprompttext, SIZEOF(saveprompttext));
140 _stprintf(temptext, saveprompttext, filename);
141 switch (MessageBox(hwnd, temptext, programname, MB_YESNOCANCEL | MB_ICONQUESTION))
142 {
143 case IDNO:
144 DestroyWindow(hwnd);
145 break;
146 case IDYES:
147 SendMessage(hwnd, WM_COMMAND, IDM_FILESAVEAS, 0);
148 DestroyWindow(hwnd);
149 break;
150 }
151 }
152 else
153 {
154 DestroyWindow(hwnd);
155 }
156 break;
157
158 case WM_INITMENUPOPUP:
159 switch (lParam)
160 {
161 case 0:
162 if (isAFile)
163 {
164 EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERPLANE,
165 MF_ENABLED | MF_BYCOMMAND);
166 EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERCENTERED,
167 MF_ENABLED | MF_BYCOMMAND);
168 EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERSTRETCHED,
169 MF_ENABLED | MF_BYCOMMAND);
170 }
171 else
172 {
173 EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERPLANE,
174 MF_GRAYED | MF_BYCOMMAND);
175 EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERCENTERED,
176 MF_GRAYED | MF_BYCOMMAND);
177 EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERSTRETCHED,
178 MF_GRAYED | MF_BYCOMMAND);
179 }
180 break;
181 case 1:
182 if (undoSteps > 0)
183 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITUNDO, MF_ENABLED | MF_BYCOMMAND);
184 else
185 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITUNDO, MF_GRAYED | MF_BYCOMMAND);
186 if (redoSteps > 0)
187 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITREDO, MF_ENABLED | MF_BYCOMMAND);
188 else
189 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITREDO, MF_GRAYED | MF_BYCOMMAND);
190 if (IsWindowVisible(hSelection))
191 {
192 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCUT, MF_ENABLED | MF_BYCOMMAND);
193 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPY, MF_ENABLED | MF_BYCOMMAND);
194 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITDELETESELECTION, MF_ENABLED | MF_BYCOMMAND);
195 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITINVERTSELECTION, MF_ENABLED | MF_BYCOMMAND);
196 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPYTO, MF_ENABLED | MF_BYCOMMAND);
197 }
198 else
199 {
200 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCUT, MF_GRAYED | MF_BYCOMMAND);
201 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPY, MF_GRAYED | MF_BYCOMMAND);
202 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITDELETESELECTION, MF_GRAYED | MF_BYCOMMAND);
203 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITINVERTSELECTION, MF_GRAYED | MF_BYCOMMAND);
204 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPYTO, MF_GRAYED | MF_BYCOMMAND);
205 }
206 OpenClipboard(hMainWnd);
207 if (GetClipboardData(CF_BITMAP) != NULL)
208 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITPASTE, MF_ENABLED | MF_BYCOMMAND);
209 else
210 EnableMenuItem(GetMenu(hMainWnd), IDM_EDITPASTE, MF_GRAYED | MF_BYCOMMAND);
211 CloseClipboard();
212 break;
213 case 3:
214 if (IsWindowVisible(hSelection))
215 EnableMenuItem(GetMenu(hMainWnd), IDM_IMAGECROP, MF_ENABLED | MF_BYCOMMAND);
216 else
217 EnableMenuItem(GetMenu(hMainWnd), IDM_IMAGECROP, MF_GRAYED | MF_BYCOMMAND);
218 CheckMenuItem(GetMenu(hMainWnd), IDM_IMAGEDRAWOPAQUE, (transpBg == 0) ?
219 (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
220 break;
221 }
222 if (IsWindowVisible(hStatusBar))
223 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWSTATUSBAR, MF_CHECKED | MF_BYCOMMAND);
224 else
225 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWSTATUSBAR, MF_UNCHECKED | MF_BYCOMMAND);
226
227 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWSHOWGRID,
228 showGrid ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
229 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWSHOWMINIATURE,
230 showMiniature ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
231
232 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM125,
233 (zoom == 125) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
234 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM25,
235 (zoom == 250) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
236 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM50,
237 (zoom == 500) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
238 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM100,
239 (zoom == 1000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
240 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM200,
241 (zoom == 2000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
242 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM400,
243 (zoom == 4000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
244 CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM800,
245 (zoom == 8000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
246
247 break;
248
249 case WM_SIZE:
250 if (hwnd == hMainWnd)
251 {
252 int test[] = { LOWORD(lParam) - 260, LOWORD(lParam) - 140, LOWORD(lParam) - 20 };
253 SendMessage(hStatusBar, WM_SIZE, wParam, lParam);
254 SendMessage(hStatusBar, SB_SETPARTS, 3, (int)&test);
255 MoveWindow(hScrollbox, 56, 49, LOWORD(lParam) - 56, HIWORD(lParam) - 72, TRUE);
256 //InvalidateRect(hwnd, NULL, TRUE);
257 }
258 if (hwnd == hImageArea)
259 {
260 MoveWindow(hSizeboxLeftTop,
261 0,
262 0, 3, 3, TRUE);
263 MoveWindow(hSizeboxCenterTop,
264 imgXRes * zoom / 2000 + 3 * 3 / 4,
265 0, 3, 3, TRUE);
266 MoveWindow(hSizeboxRightTop,
267 imgXRes * zoom / 1000 + 3,
268 0, 3, 3, TRUE);
269 MoveWindow(hSizeboxLeftCenter,
270 0,
271 imgYRes * zoom / 2000 + 3 * 3 / 4, 3, 3, TRUE);
272 MoveWindow(hSizeboxRightCenter,
273 imgXRes * zoom / 1000 + 3,
274 imgYRes * zoom / 2000 + 3 * 3 / 4, 3, 3, TRUE);
275 MoveWindow(hSizeboxLeftBottom,
276 0,
277 imgYRes * zoom / 1000 + 3, 3, 3, TRUE);
278 MoveWindow(hSizeboxCenterBottom,
279 imgXRes * zoom / 2000 + 3 * 3 / 4,
280 imgYRes * zoom / 1000 + 3, 3, 3, TRUE);
281 MoveWindow(hSizeboxRightBottom,
282 imgXRes * zoom / 1000 + 3,
283 imgYRes * zoom / 1000 + 3, 3, 3, TRUE);
284 }
285 if ((hwnd == hImageArea) || (hwnd == hScrollbox))
286 {
287 long clientRectScrollbox[4];
288 long clientRectImageArea[4];
289 SCROLLINFO si;
290 GetClientRect(hScrollbox, (LPRECT) &clientRectScrollbox);
291 GetClientRect(hImageArea, (LPRECT) &clientRectImageArea);
292 si.cbSize = sizeof(SCROLLINFO);
293 si.fMask = SIF_PAGE | SIF_RANGE;
294 si.nMax = clientRectImageArea[2] + 6 - 1;
295 si.nMin = 0;
296 si.nPage = clientRectScrollbox[2];
297 SetScrollInfo(hScrollbox, SB_HORZ, &si, TRUE);
298 GetClientRect(hScrollbox, (LPRECT) clientRectScrollbox);
299 si.nMax = clientRectImageArea[3] + 6 - 1;
300 si.nPage = clientRectScrollbox[3];
301 SetScrollInfo(hScrollbox, SB_VERT, &si, TRUE);
302 MoveWindow(hScrlClient,
303 -GetScrollPos(hScrollbox, SB_HORZ), -GetScrollPos(hScrollbox, SB_VERT),
304 max(clientRectImageArea[2] + 6, clientRectScrollbox[2]),
305 max(clientRectImageArea[3] + 6, clientRectScrollbox[3]), TRUE);
306 }
307 break;
308
309 case WM_HSCROLL:
310 if (hwnd == hScrollbox)
311 {
312 SCROLLINFO si;
313 si.cbSize = sizeof(SCROLLINFO);
314 si.fMask = SIF_ALL;
315 GetScrollInfo(hScrollbox, SB_HORZ, &si);
316 switch (LOWORD(wParam))
317 {
318 case SB_THUMBTRACK:
319 case SB_THUMBPOSITION:
320 si.nPos = HIWORD(wParam);
321 break;
322 case SB_LINELEFT:
323 si.nPos -= 5;
324 break;
325 case SB_LINERIGHT:
326 si.nPos += 5;
327 break;
328 case SB_PAGELEFT:
329 si.nPos -= si.nPage;
330 break;
331 case SB_PAGERIGHT:
332 si.nPos += si.nPage;
333 break;
334 }
335 SetScrollInfo(hScrollbox, SB_HORZ, &si, TRUE);
336 MoveWindow(hScrlClient, -GetScrollPos(hScrollbox, SB_HORZ),
337 -GetScrollPos(hScrollbox, SB_VERT), imgXRes * zoom / 1000 + 6,
338 imgYRes * zoom / 1000 + 6, TRUE);
339 }
340 break;
341
342 case WM_VSCROLL:
343 if (hwnd == hScrollbox)
344 {
345 SCROLLINFO si;
346 si.cbSize = sizeof(SCROLLINFO);
347 si.fMask = SIF_ALL;
348 GetScrollInfo(hScrollbox, SB_VERT, &si);
349 switch (LOWORD(wParam))
350 {
351 case SB_THUMBTRACK:
352 case SB_THUMBPOSITION:
353 si.nPos = HIWORD(wParam);
354 break;
355 case SB_LINEUP:
356 si.nPos -= 5;
357 break;
358 case SB_LINEDOWN:
359 si.nPos += 5;
360 break;
361 case SB_PAGEUP:
362 si.nPos -= si.nPage;
363 break;
364 case SB_PAGEDOWN:
365 si.nPos += si.nPage;
366 break;
367 }
368 SetScrollInfo(hScrollbox, SB_VERT, &si, TRUE);
369 MoveWindow(hScrlClient, -GetScrollPos(hScrollbox, SB_HORZ),
370 -GetScrollPos(hScrollbox, SB_VERT), imgXRes * zoom / 1000 + 6,
371 imgYRes * zoom / 1000 + 6, TRUE);
372 }
373 break;
374
375 case WM_GETMINMAXINFO:
376 if (hwnd == hMainWnd)
377 {
378 MINMAXINFO *mm = (LPMINMAXINFO) lParam;
379 (*mm).ptMinTrackSize.x = 330;
380 (*mm).ptMinTrackSize.y = 430;
381 }
382 break;
383
384 case WM_PAINT:
385 DefWindowProc(hwnd, message, wParam, lParam);
386 if (hwnd == hImageArea)
387 {
388 HDC hdc = GetDC(hImageArea);
389 StretchBlt(hdc, 0, 0, imgXRes * zoom / 1000, imgYRes * zoom / 1000, hDrawingDC, 0, 0, imgXRes,
390 imgYRes, SRCCOPY);
391 if (showGrid && (zoom >= 4000))
392 {
393 HPEN oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
394 int counter;
395 for(counter = 0; counter <= imgYRes; counter++)
396 {
397 MoveToEx(hdc, 0, counter * zoom / 1000, NULL);
398 LineTo(hdc, imgXRes * zoom / 1000, counter * zoom / 1000);
399 }
400 for(counter = 0; counter <= imgXRes; counter++)
401 {
402 MoveToEx(hdc, counter * zoom / 1000, 0, NULL);
403 LineTo(hdc, counter * zoom / 1000, imgYRes * zoom / 1000);
404 }
405 DeleteObject(SelectObject(hdc, oldPen));
406 }
407 ReleaseDC(hImageArea, hdc);
408 SendMessage(hSelection, WM_PAINT, 0, 0);
409 SendMessage(hwndMiniature, WM_PAINT, 0, 0);
410 }
411 else if (hwnd == hwndMiniature)
412 {
413 long mclient[4];
414 HDC hdc;
415 GetClientRect(hwndMiniature, (LPRECT) &mclient);
416 hdc = GetDC(hwndMiniature);
417 BitBlt(hdc, -min(imgXRes * GetScrollPos(hScrollbox, SB_HORZ) / 10000, imgXRes - mclient[2]),
418 -min(imgYRes * GetScrollPos(hScrollbox, SB_VERT) / 10000, imgYRes - mclient[3]),
419 imgXRes, imgYRes, hDrawingDC, 0, 0, SRCCOPY);
420 ReleaseDC(hwndMiniature, hdc);
421 }
422 break;
423
424 // mouse events used for drawing
425
426 case WM_SETCURSOR:
427 if (hwnd == hImageArea)
428 {
429 switch (activeTool)
430 {
431 case 4:
432 SetCursor(hCurFill);
433 break;
434 case 5:
435 SetCursor(hCurColor);
436 break;
437 case 6:
438 SetCursor(hCurZoom);
439 break;
440 case 7:
441 SetCursor(hCurPen);
442 break;
443 case 9:
444 SetCursor(hCurAirbrush);
445 break;
446 default:
447 SetCursor(LoadCursor(NULL, IDC_CROSS));
448 }
449 }
450 else
451 DefWindowProc(hwnd, message, wParam, lParam);
452 break;
453
454 case WM_LBUTTONDOWN:
455 if (hwnd == hImageArea)
456 {
457 if ((!drawing) || (activeTool == 5))
458 {
459 SetCapture(hImageArea);
460 drawing = TRUE;
461 startPaintingL(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom,
462 fgColor, bgColor);
463 }
464 else
465 {
466 SendMessage(hwnd, WM_LBUTTONUP, wParam, lParam);
467 undo();
468 }
469 SendMessage(hImageArea, WM_PAINT, 0, 0);
470 if ((activeTool == 6) && (zoom < 8000))
471 zoomTo(zoom * 2, (short)LOWORD(lParam), (short)HIWORD(lParam));
472 }
473 break;
474
475 case WM_RBUTTONDOWN:
476 if (hwnd == hImageArea)
477 {
478 if ((!drawing) || (activeTool == 5))
479 {
480 SetCapture(hImageArea);
481 drawing = TRUE;
482 startPaintingR(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom,
483 fgColor, bgColor);
484 }
485 else
486 {
487 SendMessage(hwnd, WM_RBUTTONUP, wParam, lParam);
488 undo();
489 }
490 SendMessage(hImageArea, WM_PAINT, 0, 0);
491 if ((activeTool == 6) && (zoom > 125))
492 zoomTo(zoom / 2, (short)LOWORD(lParam), (short)HIWORD(lParam));
493 }
494 break;
495
496 case WM_LBUTTONUP:
497 if ((hwnd == hImageArea) && drawing)
498 {
499 ReleaseCapture();
500 drawing = FALSE;
501 endPaintingL(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom, fgColor,
502 bgColor);
503 SendMessage(hImageArea, WM_PAINT, 0, 0);
504 if (activeTool == 5)
505 {
506 int tempColor =
507 GetPixel(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom);
508 if (tempColor != CLR_INVALID)
509 fgColor = tempColor;
510 SendMessage(hPalWin, WM_PAINT, 0, 0);
511 }
512 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
513 }
514 break;
515
516 case WM_RBUTTONUP:
517 if ((hwnd == hImageArea) && drawing)
518 {
519 ReleaseCapture();
520 drawing = FALSE;
521 endPaintingR(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom, fgColor,
522 bgColor);
523 SendMessage(hImageArea, WM_PAINT, 0, 0);
524 if (activeTool == 5)
525 {
526 int tempColor =
527 GetPixel(hDrawingDC, LOWORD(lParam) * 1000 / zoom, HIWORD(lParam) * 1000 / zoom);
528 if (tempColor != CLR_INVALID)
529 bgColor = tempColor;
530 SendMessage(hPalWin, WM_PAINT, 0, 0);
531 }
532 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
533 }
534 break;
535
536 case WM_MOUSEMOVE:
537 if (hwnd == hImageArea)
538 {
539 if ((!drawing) || (activeTool <= 9))
540 {
541 TRACKMOUSEEVENT tme;
542
543 TCHAR coordStr[100];
544 _stprintf(coordStr, _T("%d, %d"), (short)LOWORD(lParam) * 1000 / zoom,
545 (short)HIWORD(lParam) * 1000 / zoom);
546 SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr);
547
548 if (activeTool == 6)
549 {
550 SendMessage(hImageArea, WM_PAINT, 0, 0);
551 drawZoomFrame((short)LOWORD(lParam), (short)HIWORD(lParam));
552 }
553
554 tme.cbSize = sizeof(TRACKMOUSEEVENT);
555 tme.dwFlags = TME_LEAVE;
556 tme.hwndTrack = hImageArea;
557 tme.dwHoverTime = 0;
558 TrackMouseEvent(&tme);
559 }
560 if (drawing)
561 {
562 if ((wParam & MK_LBUTTON) != 0)
563 {
564 whilePaintingL(hDrawingDC, (short)LOWORD(lParam) * 1000 / zoom,
565 (short)HIWORD(lParam) * 1000 / zoom, fgColor, bgColor);
566 SendMessage(hImageArea, WM_PAINT, 0, 0);
567 if ((activeTool >= 10) || (activeTool == 2))
568 {
569 TCHAR sizeStr[100];
570 _stprintf(sizeStr, _T("%d x %d"), (short)LOWORD(lParam) * 1000 / zoom - startX,
571 (short)HIWORD(lParam) * 1000 / zoom - startY);
572 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
573 }
574 }
575 if ((wParam & MK_RBUTTON) != 0)
576 {
577 whilePaintingR(hDrawingDC, (short)LOWORD(lParam) * 1000 / zoom,
578 (short)HIWORD(lParam) * 1000 / zoom, fgColor, bgColor);
579 SendMessage(hImageArea, WM_PAINT, 0, 0);
580 if (activeTool >= 10)
581 {
582 TCHAR sizeStr[100];
583 _stprintf(sizeStr, _T("%d x %d"), (short)LOWORD(lParam) * 1000 / zoom - startX,
584 (short)HIWORD(lParam) * 1000 / zoom - startY);
585 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
586 }
587 }
588 }
589 }
590 break;
591
592 case WM_MOUSELEAVE:
593 SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) _T(""));
594 if (activeTool == 6)
595 SendMessage(hImageArea, WM_PAINT, 0, 0);
596 break;
597
598 // menu and button events
599
600 case WM_COMMAND:
601 switch (LOWORD(wParam))
602 {
603 case IDM_HELPINFO:
604 {
605 HICON paintIcon = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON));
606 TCHAR infotitle[100];
607 TCHAR infotext[200];
608 LoadString(hProgInstance, IDS_INFOTITLE, infotitle, SIZEOF(infotitle));
609 LoadString(hProgInstance, IDS_INFOTEXT, infotext, SIZEOF(infotext));
610 ShellAbout(hMainWnd, infotitle, infotext, paintIcon);
611 DeleteObject(paintIcon);
612 break;
613 }
614 case IDM_HELPHELPTOPICS:
615 //HtmlHelp(hMainWnd, "help\\Paint.chm", 0, 0);
616 break;
617 case IDM_FILEEXIT:
618 SendMessage(hwnd, WM_CLOSE, wParam, lParam);
619 break;
620 case IDM_FILENEW:
621 Rectangle(hDrawingDC, 0 - 1, 0 - 1, imgXRes + 1, imgYRes + 1);
622 SendMessage(hImageArea, WM_PAINT, 0, 0);
623 break;
624 case IDM_FILEOPEN:
625 if (GetOpenFileName(&ofn) != 0)
626 {
627 HBITMAP bmNew = NULL;
628 LoadDIBFromFile(&bmNew, ofn.lpstrFile, &fileTime, &fileSize, &fileHPPM, &fileVPPM);
629 if (bmNew != NULL)
630 {
631 TCHAR tempstr[1000];
632 TCHAR resstr[100];
633 insertReversible(bmNew);
634 updateCanvasAndScrollbars();
635 CopyMemory(filename, ofn.lpstrFileTitle, sizeof(filename));
636 CopyMemory(filepathname, ofn.lpstrFileTitle, sizeof(filepathname));
637 LoadString(hProgInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
638 _stprintf(tempstr, resstr, filename);
639 SetWindowText(hMainWnd, tempstr);
640 clearHistory();
641 isAFile = TRUE;
642 }
643 }
644 break;
645 case IDM_FILESAVE:
646 if (isAFile)
647 {
648 SaveDIBToFile(hBms[currInd], filepathname, hDrawingDC, &fileTime, &fileSize, fileHPPM,
649 fileVPPM);
650 imageSaved = TRUE;
651 }
652 else
653 SendMessage(hwnd, WM_COMMAND, IDM_FILESAVEAS, 0);
654 break;
655 case IDM_FILESAVEAS:
656 if (GetSaveFileName(&sfn) != 0)
657 {
658 TCHAR tempstr[1000];
659 TCHAR resstr[100];
660 SaveDIBToFile(hBms[currInd], sfn.lpstrFile, hDrawingDC, &fileTime, &fileSize,
661 fileHPPM, fileVPPM);
662 CopyMemory(filename, sfn.lpstrFileTitle, sizeof(filename));
663 CopyMemory(filepathname, sfn.lpstrFile, sizeof(filepathname));
664 LoadString(hProgInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
665 _stprintf(tempstr, resstr, filename);
666 SetWindowText(hMainWnd, tempstr);
667 isAFile = TRUE;
668 imageSaved = TRUE;
669 }
670 break;
671 case IDM_FILEASWALLPAPERPLANE:
672 SetWallpaper(filepathname, 1, 1);
673 break;
674 case IDM_FILEASWALLPAPERCENTERED:
675 SetWallpaper(filepathname, 1, 0);
676 break;
677 case IDM_FILEASWALLPAPERSTRETCHED:
678 SetWallpaper(filepathname, 2, 0);
679 break;
680 case IDM_EDITUNDO:
681 undo();
682 SendMessage(hImageArea, WM_PAINT, 0, 0);
683 break;
684 case IDM_EDITREDO:
685 redo();
686 SendMessage(hImageArea, WM_PAINT, 0, 0);
687 break;
688 case IDM_EDITCOPY:
689 OpenClipboard(hMainWnd);
690 EmptyClipboard();
691 SetClipboardData(CF_BITMAP, CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
692 CloseClipboard();
693 break;
694 case IDM_EDITPASTE:
695 OpenClipboard(hMainWnd);
696 if (GetClipboardData(CF_BITMAP) != NULL)
697 {
698 DeleteObject(SelectObject(hSelDC, hSelBm = CopyImage(GetClipboardData(CF_BITMAP),
699 IMAGE_BITMAP, 0, 0,
700 LR_COPYRETURNORG)));
701 newReversible();
702 rectSel_src[0] = rectSel_src[1] = rectSel_src[2] = rectSel_src[3] = 0;
703 rectSel_dest[0] = rectSel_dest[1] = 0;
704 rectSel_dest[2] = GetDIBWidth(hSelBm);
705 rectSel_dest[3] = GetDIBHeight(hSelBm);
706 BitBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
707 hSelDC, 0, 0, SRCCOPY);
708 placeSelWin();
709 ShowWindow(hSelection, SW_SHOW);
710 }
711 CloseClipboard();
712 break;
713 case IDM_EDITDELETESELECTION:
714 ShowWindow(hSelection, SW_HIDE);
715 break;
716 case IDM_EDITSELECTALL:
717 if (activeTool == 2)
718 {
719 startPaintingL(hDrawingDC, 0, 0, fgColor, bgColor);
720 whilePaintingL(hDrawingDC, imgXRes, imgYRes, fgColor, bgColor);
721 endPaintingL(hDrawingDC, imgXRes, imgYRes, fgColor, bgColor);
722 }
723 break;
724 case IDM_EDITCOPYTO:
725 if (GetSaveFileName(&ofn) != 0)
726 SaveDIBToFile(hSelBm, ofn.lpstrFile, hDrawingDC, NULL, NULL, fileHPPM, fileVPPM);
727 break;
728 case IDM_COLORSEDITPALETTE:
729 if (ChooseColor(&choosecolor))
730 {
731 fgColor = choosecolor.rgbResult;
732 SendMessage(hPalWin, WM_PAINT, 0, 0);
733 }
734 break;
735 case IDM_IMAGEINVERTCOLORS:
736 {
737 RECT tempRect;
738 newReversible();
739 SetRect(&tempRect, 0, 0, imgXRes, imgYRes);
740 InvertRect(hDrawingDC, &tempRect);
741 SendMessage(hImageArea, WM_PAINT, 0, 0);
742 break;
743 }
744 case IDM_IMAGEDELETEIMAGE:
745 newReversible();
746 Rect(hDrawingDC, 0, 0, imgXRes, imgYRes, bgColor, bgColor, 0, TRUE);
747 SendMessage(hImageArea, WM_PAINT, 0, 0);
748 break;
749 case IDM_IMAGEROTATEMIRROR:
750 switch (mirrorRotateDlg())
751 {
752 case 1:
753 newReversible();
754 StretchBlt(hDrawingDC, imgXRes - 1, 0, -imgXRes, imgYRes, hDrawingDC, 0, 0,
755 imgXRes, imgYRes, SRCCOPY);
756 SendMessage(hImageArea, WM_PAINT, 0, 0);
757 break;
758 case 2:
759 newReversible();
760 StretchBlt(hDrawingDC, 0, imgYRes - 1, imgXRes, -imgYRes, hDrawingDC, 0, 0,
761 imgXRes, imgYRes, SRCCOPY);
762 SendMessage(hImageArea, WM_PAINT, 0, 0);
763 break;
764 case 4:
765 newReversible();
766 StretchBlt(hDrawingDC, imgXRes - 1, imgYRes - 1, -imgXRes, -imgYRes, hDrawingDC,
767 0, 0, imgXRes, imgYRes, SRCCOPY);
768 SendMessage(hImageArea, WM_PAINT, 0, 0);
769 break;
770 }
771 break;
772 case IDM_IMAGEATTRIBUTES:
773 {
774 int retVal = attributesDlg();
775 if ((LOWORD(retVal) != 0) && (HIWORD(retVal) != 0))
776 {
777 cropReversible(LOWORD(retVal), HIWORD(retVal), 0, 0);
778 updateCanvasAndScrollbars();
779 }
780 break;
781 }
782 case IDM_IMAGECHANGESIZE:
783 {
784 int retVal = changeSizeDlg();
785 if ((LOWORD(retVal) != 0) && (HIWORD(retVal) != 0))
786 {
787 insertReversible(CopyImage(hBms[currInd], IMAGE_BITMAP,
788 imgXRes * LOWORD(retVal) / 100,
789 imgYRes * HIWORD(retVal) / 100, 0));
790 updateCanvasAndScrollbars();
791 }
792 break;
793 }
794 case IDM_IMAGEDRAWOPAQUE:
795 transpBg = 1 - transpBg;
796 SendMessage(hToolSettings, WM_PAINT, 0, 0);
797 break;
798 case IDM_IMAGECROP:
799 insertReversible(CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
800 updateCanvasAndScrollbars();
801 break;
802
803 case IDM_VIEWSTATUSBAR:
804 ShowWindow(hStatusBar, IsWindowVisible(hStatusBar) ? SW_HIDE : SW_SHOW);
805 break;
806
807 case IDM_VIEWSHOWGRID:
808 showGrid = !showGrid;
809 break;
810 case IDM_VIEWSHOWMINIATURE:
811 showMiniature = !showMiniature;
812 ShowWindow(hwndMiniature, showMiniature ? SW_SHOW : SW_HIDE);
813 break;
814
815 case IDM_VIEWZOOM125:
816 zoomTo(125, 0, 0);
817 break;
818 case IDM_VIEWZOOM25:
819 zoomTo(250, 0, 0);
820 break;
821 case IDM_VIEWZOOM50:
822 zoomTo(500, 0, 0);
823 break;
824 case IDM_VIEWZOOM100:
825 zoomTo(1000, 0, 0);
826 break;
827 case IDM_VIEWZOOM200:
828 zoomTo(2000, 0, 0);
829 break;
830 case IDM_VIEWZOOM400:
831 zoomTo(4000, 0, 0);
832 break;
833 case IDM_VIEWZOOM800:
834 zoomTo(8000, 0, 0);
835 break;
836 case ID_FREESEL:
837 selectTool(1);
838 break;
839 case ID_RECTSEL:
840 selectTool(2);
841 break;
842 case ID_RUBBER:
843 selectTool(3);
844 break;
845 case ID_FILL:
846 selectTool(4);
847 break;
848 case ID_COLOR:
849 selectTool(5);
850 break;
851 case ID_ZOOM:
852 selectTool(6);
853 break;
854 case ID_PEN:
855 selectTool(7);
856 break;
857 case ID_BRUSH:
858 selectTool(8);
859 break;
860 case ID_AIRBRUSH:
861 selectTool(9);
862 break;
863 case ID_TEXT:
864 selectTool(10);
865 break;
866 case ID_LINE:
867 selectTool(11);
868 break;
869 case ID_BEZIER:
870 selectTool(12);
871 break;
872 case ID_RECT:
873 selectTool(13);
874 break;
875 case ID_SHAPE:
876 selectTool(14);
877 break;
878 case ID_ELLIPSE:
879 selectTool(15);
880 break;
881 case ID_RRECT:
882 selectTool(16);
883 break;
884 }
885 break;
886 default:
887 return DefWindowProc(hwnd, message, wParam, lParam);
888 }
889
890 return 0;
891 }