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