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