2 * PROJECT: PAINT for ReactOS
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
10 /* INCLUDES *********************************************************/
19 /* FUNCTIONS ********************************************************/
24 ShowWindow(hSelection
, SW_HIDE
);
26 pointSP
= 0; // resets the point-buffer of the polygon and bezier functions
27 InvalidateRect(hToolSettings
, NULL
, TRUE
);
28 ShowWindow(hTrackbarZoom
, (tool
== 6) ? SW_SHOW
: SW_HIDE
);
32 updateCanvasAndScrollbars()
34 ShowWindow(hSelection
, SW_HIDE
);
35 MoveWindow(hImageArea
, 3, 3, imgXRes
* zoom
/ 1000, imgYRes
* zoom
/ 1000, FALSE
);
36 InvalidateRect(hScrollbox
, NULL
, TRUE
);
37 InvalidateRect(hImageArea
, NULL
, FALSE
);
39 SetScrollPos(hScrollbox
, SB_HORZ
, 0, TRUE
);
40 SetScrollPos(hScrollbox
, SB_VERT
, 0, TRUE
);
44 zoomTo(int newZoom
, int mouseX
, int mouseY
)
47 int tempZoom
= newZoom
;
49 long clientRectScrollbox
[4];
50 long clientRectImageArea
[4];
52 GetClientRect(hScrollbox
, (LPRECT
) &clientRectScrollbox
);
53 GetClientRect(hImageArea
, (LPRECT
) &clientRectImageArea
);
54 w
= clientRectImageArea
[2] * clientRectScrollbox
[2] / (clientRectImageArea
[2] * newZoom
/ zoom
);
55 h
= clientRectImageArea
[3] * clientRectScrollbox
[3] / (clientRectImageArea
[3] * newZoom
/ zoom
);
56 x
= max(0, min(clientRectImageArea
[2] - w
, mouseX
- w
/ 2)) * newZoom
/ zoom
;
57 y
= max(0, min(clientRectImageArea
[3] - h
, mouseY
- h
/ 2)) * newZoom
/ zoom
;
61 ShowWindow(hSelection
, SW_HIDE
);
62 MoveWindow(hImageArea
, 3, 3, imgXRes
* zoom
/ 1000, imgYRes
* zoom
/ 1000, FALSE
);
63 InvalidateRect(hScrollbox
, NULL
, TRUE
);
64 InvalidateRect(hImageArea
, NULL
, FALSE
);
66 SendMessage(hScrollbox
, WM_HSCROLL
, SB_THUMBPOSITION
| (x
<< 16), 0);
67 SendMessage(hScrollbox
, WM_VSCROLL
, SB_THUMBPOSITION
| (y
<< 16), 0);
69 while (tempZoom
> 125)
72 tempZoom
= tempZoom
>> 1;
74 SendMessage(hTrackbarZoom
, TBM_SETPOS
, (WPARAM
) TRUE
, (LPARAM
) tbPos
);
78 drawZoomFrame(int mouseX
, int mouseY
)
86 long clientRectScrollbox
[4];
87 long clientRectImageArea
[4];
89 GetClientRect(hScrollbox
, (LPRECT
) &clientRectScrollbox
);
90 GetClientRect(hImageArea
, (LPRECT
) &clientRectImageArea
);
91 w
= clientRectImageArea
[2] * clientRectScrollbox
[2] / (clientRectImageArea
[2] * 2);
92 h
= clientRectImageArea
[3] * clientRectScrollbox
[3] / (clientRectImageArea
[3] * 2);
93 x
= max(0, min(clientRectImageArea
[2] - w
, mouseX
- w
/ 2));
94 y
= max(0, min(clientRectImageArea
[3] - h
, mouseY
- h
/ 2));
96 hdc
= GetDC(hImageArea
);
97 oldPen
= SelectObject(hdc
, CreatePen(PS_SOLID
, 0, 0));
98 logbrush
.lbStyle
= BS_HOLLOW
;
99 oldBrush
= SelectObject(hdc
, CreateBrushIndirect(&logbrush
));
100 rop
= SetROP2(hdc
, R2_NOT
);
101 Rectangle(hdc
, x
, y
, x
+ w
, y
+ h
);
103 DeleteObject(SelectObject(hdc
, oldBrush
));
104 DeleteObject(SelectObject(hdc
, oldPen
));
105 ReleaseDC(hImageArea
, hdc
);
109 alignChildrenToMainWindow()
113 GetClientRect(hMainWnd
, &clientRect
);
115 if (IsWindowVisible(hToolBoxContainer
))
118 w
= clientRect
.right
- 56;
123 w
= clientRect
.right
;
125 if (IsWindowVisible(hPalWin
))
128 h
= clientRect
.bottom
- 49;
133 h
= clientRect
.bottom
- 3;
136 MoveWindow(hScrollbox
, x
, y
, w
, IsWindowVisible(hStatusBar
) ? h
- 23 : h
, TRUE
);
137 MoveWindow(hPalWin
, x
, 9, 255, 32, TRUE
);
141 saveImage(BOOL overwrite
)
143 if (isAFile
&& overwrite
)
145 SaveDIBToFile(hBms
[currInd
], filepathname
, hDrawingDC
, &fileTime
, &fileSize
, fileHPPM
,
149 else if (GetSaveFileName(&sfn
) != 0)
153 SaveDIBToFile(hBms
[currInd
], sfn
.lpstrFile
, hDrawingDC
, &fileTime
, &fileSize
,
155 CopyMemory(filename
, sfn
.lpstrFileTitle
, sizeof(filename
));
156 CopyMemory(filepathname
, sfn
.lpstrFile
, sizeof(filepathname
));
157 LoadString(hProgInstance
, IDS_WINDOWTITLE
, resstr
, SIZEOF(resstr
));
158 _stprintf(tempstr
, resstr
, filename
);
159 SetWindowText(hMainWnd
, tempstr
);
168 WindowProcedure(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
170 switch (message
) /* handle the messages */
178 PostQuitMessage(0); /* send a WM_QUIT to the message queue */
182 if (hwnd
== hwndMiniature
)
184 ShowWindow(hwndMiniature
, SW_HIDE
);
185 showMiniature
= FALSE
;
190 TCHAR programname
[20];
191 TCHAR saveprompttext
[100];
193 LoadString(hProgInstance
, IDS_PROGRAMNAME
, programname
, SIZEOF(programname
));
194 LoadString(hProgInstance
, IDS_SAVEPROMPTTEXT
, saveprompttext
, SIZEOF(saveprompttext
));
195 _stprintf(temptext
, saveprompttext
, filename
);
196 switch (MessageBox(hwnd
, temptext
, programname
, MB_YESNOCANCEL
| MB_ICONQUESTION
))
214 case WM_INITMENUPOPUP
:
220 EnableMenuItem(GetMenu(hMainWnd
), IDM_FILEASWALLPAPERPLANE
,
221 MF_ENABLED
| MF_BYCOMMAND
);
222 EnableMenuItem(GetMenu(hMainWnd
), IDM_FILEASWALLPAPERCENTERED
,
223 MF_ENABLED
| MF_BYCOMMAND
);
224 EnableMenuItem(GetMenu(hMainWnd
), IDM_FILEASWALLPAPERSTRETCHED
,
225 MF_ENABLED
| MF_BYCOMMAND
);
229 EnableMenuItem(GetMenu(hMainWnd
), IDM_FILEASWALLPAPERPLANE
,
230 MF_GRAYED
| MF_BYCOMMAND
);
231 EnableMenuItem(GetMenu(hMainWnd
), IDM_FILEASWALLPAPERCENTERED
,
232 MF_GRAYED
| MF_BYCOMMAND
);
233 EnableMenuItem(GetMenu(hMainWnd
), IDM_FILEASWALLPAPERSTRETCHED
,
234 MF_GRAYED
| MF_BYCOMMAND
);
238 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITUNDO
,
239 (undoSteps
> 0) ? (MF_ENABLED
| MF_BYCOMMAND
) : (MF_GRAYED
| MF_BYCOMMAND
));
240 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITREDO
,
241 (redoSteps
> 0) ? (MF_ENABLED
| MF_BYCOMMAND
) : (MF_GRAYED
| MF_BYCOMMAND
));
242 if (IsWindowVisible(hSelection
))
244 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITCUT
, MF_ENABLED
| MF_BYCOMMAND
);
245 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITCOPY
, MF_ENABLED
| MF_BYCOMMAND
);
246 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITDELETESELECTION
, MF_ENABLED
| MF_BYCOMMAND
);
247 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITINVERTSELECTION
, MF_ENABLED
| MF_BYCOMMAND
);
248 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITCOPYTO
, MF_ENABLED
| MF_BYCOMMAND
);
252 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITCUT
, MF_GRAYED
| MF_BYCOMMAND
);
253 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITCOPY
, MF_GRAYED
| MF_BYCOMMAND
);
254 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITDELETESELECTION
, MF_GRAYED
| MF_BYCOMMAND
);
255 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITINVERTSELECTION
, MF_GRAYED
| MF_BYCOMMAND
);
256 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITCOPYTO
, MF_GRAYED
| MF_BYCOMMAND
);
258 OpenClipboard(hMainWnd
);
259 if (GetClipboardData(CF_BITMAP
) != NULL
)
260 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITPASTE
, MF_ENABLED
| MF_BYCOMMAND
);
262 EnableMenuItem(GetMenu(hMainWnd
), IDM_EDITPASTE
, MF_GRAYED
| MF_BYCOMMAND
);
266 if (IsWindowVisible(hSelection
))
267 EnableMenuItem(GetMenu(hMainWnd
), IDM_IMAGECROP
, MF_ENABLED
| MF_BYCOMMAND
);
269 EnableMenuItem(GetMenu(hMainWnd
), IDM_IMAGECROP
, MF_GRAYED
| MF_BYCOMMAND
);
270 CheckMenuItem(GetMenu(hMainWnd
), IDM_IMAGEDRAWOPAQUE
, (transpBg
== 0) ?
271 (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
274 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWTOOLBOX
,
275 IsWindowVisible(hToolBoxContainer
) ?
276 (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
277 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWCOLORPALETTE
,
278 IsWindowVisible(hPalWin
) ?
279 (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
280 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWSTATUSBAR
,
281 IsWindowVisible(hStatusBar
) ?
282 (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
284 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWSHOWGRID
,
285 showGrid
? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
286 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWSHOWMINIATURE
,
287 showMiniature
? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
289 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWZOOM125
,
290 (zoom
== 125) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
291 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWZOOM25
,
292 (zoom
== 250) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
293 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWZOOM50
,
294 (zoom
== 500) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
295 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWZOOM100
,
296 (zoom
== 1000) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
297 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWZOOM200
,
298 (zoom
== 2000) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
299 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWZOOM400
,
300 (zoom
== 4000) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
301 CheckMenuItem(GetMenu(hMainWnd
), IDM_VIEWZOOM800
,
302 (zoom
== 8000) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
304 CheckMenuItem(GetMenu(hMainWnd
), IDM_COLORSMODERNPALETTE
,
305 (selectedPalette
== 1) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
306 CheckMenuItem(GetMenu(hMainWnd
), IDM_COLORSOLDPALETTE
,
307 (selectedPalette
== 2) ? (MF_CHECKED
| MF_BYCOMMAND
) : (MF_UNCHECKED
| MF_BYCOMMAND
));
311 if (hwnd
== hMainWnd
)
313 int test
[] = { LOWORD(lParam
) - 260, LOWORD(lParam
) - 140, LOWORD(lParam
) - 20 };
314 SendMessage(hStatusBar
, WM_SIZE
, wParam
, lParam
);
315 SendMessage(hStatusBar
, SB_SETPARTS
, 3, (LPARAM
)&test
);
316 alignChildrenToMainWindow();
317 InvalidateRect(hwnd
, NULL
, TRUE
);
319 if (hwnd
== hImageArea
)
321 MoveWindow(hSizeboxLeftTop
,
324 MoveWindow(hSizeboxCenterTop
,
325 imgXRes
* zoom
/ 2000 + 3 * 3 / 4,
327 MoveWindow(hSizeboxRightTop
,
328 imgXRes
* zoom
/ 1000 + 3,
330 MoveWindow(hSizeboxLeftCenter
,
332 imgYRes
* zoom
/ 2000 + 3 * 3 / 4, 3, 3, TRUE
);
333 MoveWindow(hSizeboxRightCenter
,
334 imgXRes
* zoom
/ 1000 + 3,
335 imgYRes
* zoom
/ 2000 + 3 * 3 / 4, 3, 3, TRUE
);
336 MoveWindow(hSizeboxLeftBottom
,
338 imgYRes
* zoom
/ 1000 + 3, 3, 3, TRUE
);
339 MoveWindow(hSizeboxCenterBottom
,
340 imgXRes
* zoom
/ 2000 + 3 * 3 / 4,
341 imgYRes
* zoom
/ 1000 + 3, 3, 3, TRUE
);
342 MoveWindow(hSizeboxRightBottom
,
343 imgXRes
* zoom
/ 1000 + 3,
344 imgYRes
* zoom
/ 1000 + 3, 3, 3, TRUE
);
346 if ((hwnd
== hImageArea
) || (hwnd
== hScrollbox
))
348 long clientRectScrollbox
[4];
349 long clientRectImageArea
[4];
351 GetClientRect(hScrollbox
, (LPRECT
) &clientRectScrollbox
);
352 GetClientRect(hImageArea
, (LPRECT
) &clientRectImageArea
);
353 si
.cbSize
= sizeof(SCROLLINFO
);
354 si
.fMask
= SIF_PAGE
| SIF_RANGE
;
355 si
.nMax
= clientRectImageArea
[2] + 6 - 1;
357 si
.nPage
= clientRectScrollbox
[2];
358 SetScrollInfo(hScrollbox
, SB_HORZ
, &si
, TRUE
);
359 GetClientRect(hScrollbox
, (LPRECT
) clientRectScrollbox
);
360 si
.nMax
= clientRectImageArea
[3] + 6 - 1;
361 si
.nPage
= clientRectScrollbox
[3];
362 SetScrollInfo(hScrollbox
, SB_VERT
, &si
, TRUE
);
363 MoveWindow(hScrlClient
,
364 -GetScrollPos(hScrollbox
, SB_HORZ
), -GetScrollPos(hScrollbox
, SB_VERT
),
365 max(clientRectImageArea
[2] + 6, clientRectScrollbox
[2]),
366 max(clientRectImageArea
[3] + 6, clientRectScrollbox
[3]), TRUE
);
371 if (hwnd
== hScrollbox
)
374 si
.cbSize
= sizeof(SCROLLINFO
);
376 GetScrollInfo(hScrollbox
, SB_HORZ
, &si
);
377 switch (LOWORD(wParam
))
380 case SB_THUMBPOSITION
:
381 si
.nPos
= HIWORD(wParam
);
396 SetScrollInfo(hScrollbox
, SB_HORZ
, &si
, TRUE
);
397 MoveWindow(hScrlClient
, -GetScrollPos(hScrollbox
, SB_HORZ
),
398 -GetScrollPos(hScrollbox
, SB_VERT
), imgXRes
* zoom
/ 1000 + 6,
399 imgYRes
* zoom
/ 1000 + 6, TRUE
);
404 if (hwnd
== hScrollbox
)
407 si
.cbSize
= sizeof(SCROLLINFO
);
409 GetScrollInfo(hScrollbox
, SB_VERT
, &si
);
410 switch (LOWORD(wParam
))
413 case SB_THUMBPOSITION
:
414 si
.nPos
= HIWORD(wParam
);
429 SetScrollInfo(hScrollbox
, SB_VERT
, &si
, TRUE
);
430 MoveWindow(hScrlClient
, -GetScrollPos(hScrollbox
, SB_HORZ
),
431 -GetScrollPos(hScrollbox
, SB_VERT
), imgXRes
* zoom
/ 1000 + 6,
432 imgYRes
* zoom
/ 1000 + 6, TRUE
);
436 case WM_GETMINMAXINFO
:
437 if (hwnd
== hMainWnd
)
439 MINMAXINFO
*mm
= (LPMINMAXINFO
) lParam
;
440 mm
->ptMinTrackSize
.x
= 330;
441 mm
->ptMinTrackSize
.y
= 430;
446 DefWindowProc(hwnd
, message
, wParam
, lParam
);
447 if (hwnd
== hImageArea
)
449 HDC hdc
= GetDC(hImageArea
);
450 StretchBlt(hdc
, 0, 0, imgXRes
* zoom
/ 1000, imgYRes
* zoom
/ 1000, hDrawingDC
, 0, 0, imgXRes
,
452 if (showGrid
&& (zoom
>= 4000))
454 HPEN oldPen
= SelectObject(hdc
, CreatePen(PS_SOLID
, 1, 0x00a0a0a0));
456 for(counter
= 0; counter
<= imgYRes
; counter
++)
458 MoveToEx(hdc
, 0, counter
* zoom
/ 1000, NULL
);
459 LineTo(hdc
, imgXRes
* zoom
/ 1000, counter
* zoom
/ 1000);
461 for(counter
= 0; counter
<= imgXRes
; counter
++)
463 MoveToEx(hdc
, counter
* zoom
/ 1000, 0, NULL
);
464 LineTo(hdc
, counter
* zoom
/ 1000, imgYRes
* zoom
/ 1000);
466 DeleteObject(SelectObject(hdc
, oldPen
));
468 ReleaseDC(hImageArea
, hdc
);
469 InvalidateRect(hSelection
, NULL
, FALSE
);
470 InvalidateRect(hwndMiniature
, NULL
, FALSE
);
472 else if (hwnd
== hwndMiniature
)
476 GetClientRect(hwndMiniature
, &mclient
);
477 hdc
= GetDC(hwndMiniature
);
478 StretchBlt(hdc
, 0, 0, mclient
.right
, mclient
.bottom
, hDrawingDC
, 0, 0, imgXRes
, imgYRes
, SRCCOPY
);
479 ReleaseDC(hwndMiniature
, hdc
);
483 // mouse events used for drawing
486 if (hwnd
== hImageArea
)
494 SetCursor(hCurColor
);
503 SetCursor(hCurAirbrush
);
506 SetCursor(LoadCursor(NULL
, IDC_CROSS
));
510 DefWindowProc(hwnd
, message
, wParam
, lParam
);
514 if (hwnd
== hImageArea
)
516 if ((!drawing
) || (activeTool
== TOOL_COLOR
))
518 SetCapture(hImageArea
);
520 startPaintingL(hDrawingDC
, GET_X_LPARAM(lParam
) * 1000 / zoom
, GET_Y_LPARAM(lParam
) * 1000 / zoom
,
525 SendMessage(hwnd
, WM_LBUTTONUP
, wParam
, lParam
);
528 InvalidateRect(hImageArea
, NULL
, FALSE
);
529 if ((activeTool
== TOOL_ZOOM
) && (zoom
< 8000))
530 zoomTo(zoom
* 2, GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
));
535 if (hwnd
== hImageArea
)
537 if ((!drawing
) || (activeTool
== TOOL_COLOR
))
539 SetCapture(hImageArea
);
541 startPaintingR(hDrawingDC
, GET_X_LPARAM(lParam
) * 1000 / zoom
, GET_Y_LPARAM(lParam
) * 1000 / zoom
,
546 SendMessage(hwnd
, WM_RBUTTONUP
, wParam
, lParam
);
549 InvalidateRect(hImageArea
, NULL
, FALSE
);
550 if ((activeTool
== TOOL_ZOOM
) && (zoom
> 125))
551 zoomTo(zoom
/ 2, GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
));
556 if ((hwnd
== hImageArea
) && drawing
)
560 endPaintingL(hDrawingDC
, GET_X_LPARAM(lParam
) * 1000 / zoom
, GET_Y_LPARAM(lParam
) * 1000 / zoom
, fgColor
,
562 InvalidateRect(hImageArea
, NULL
, FALSE
);
563 if (activeTool
== TOOL_COLOR
)
566 GetPixel(hDrawingDC
, GET_X_LPARAM(lParam
) * 1000 / zoom
, GET_Y_LPARAM(lParam
) * 1000 / zoom
);
567 if (tempColor
!= CLR_INVALID
)
569 InvalidateRect(hPalWin
, NULL
, FALSE
);
571 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) "");
576 if ((hwnd
== hImageArea
) && drawing
)
580 endPaintingR(hDrawingDC
, GET_X_LPARAM(lParam
) * 1000 / zoom
, GET_Y_LPARAM(lParam
) * 1000 / zoom
, fgColor
,
582 InvalidateRect(hImageArea
, NULL
, FALSE
);
583 if (activeTool
== TOOL_COLOR
)
586 GetPixel(hDrawingDC
, GET_X_LPARAM(lParam
) * 1000 / zoom
, GET_Y_LPARAM(lParam
) * 1000 / zoom
);
587 if (tempColor
!= CLR_INVALID
)
589 InvalidateRect(hPalWin
, NULL
, FALSE
);
591 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) "");
596 if (wParam
== VK_ESCAPE
)
601 if ((activeTool
== TOOL_RECTSEL
) || (activeTool
== TOOL_FREESEL
))
603 startPaintingL(hDrawingDC
, 0, 0, fgColor
, bgColor
);
604 whilePaintingL(hDrawingDC
, 0, 0, fgColor
, bgColor
);
605 endPaintingL(hDrawingDC
, 0, 0, fgColor
, bgColor
);
606 ShowWindow(hSelection
, SW_HIDE
);
609 /* FIXME: also cancel current drawing underway */
614 if (hwnd
== hImageArea
)
616 LONG xNow
= GET_X_LPARAM(lParam
) * 1000 / zoom
;
617 LONG yNow
= GET_Y_LPARAM(lParam
) * 1000 / zoom
;
618 if ((!drawing
) || (activeTool
<= TOOL_AIRBRUSH
))
622 if (activeTool
== TOOL_ZOOM
)
624 InvalidateRect(hImageArea
, NULL
, FALSE
);
625 UpdateWindow(hImageArea
);
626 drawZoomFrame(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
));
629 tme
.cbSize
= sizeof(TRACKMOUSEEVENT
);
630 tme
.dwFlags
= TME_LEAVE
;
631 tme
.hwndTrack
= hImageArea
;
633 TrackMouseEvent(&tme
);
638 _stprintf(coordStr
, _T("%d, %d"), xNow
, yNow
);
639 SendMessage(hStatusBar
, SB_SETTEXT
, 1, (LPARAM
) coordStr
);
644 /* values displayed in statusbar */
645 LONG xRel
= xNow
- start
.x
;
646 LONG yRel
= yNow
- start
.y
;
647 /* freesel, rectsel and text tools always show numbers limited to fit into image area */
648 if ((activeTool
== TOOL_FREESEL
) || (activeTool
== TOOL_RECTSEL
) || (activeTool
== TOOL_TEXT
))
651 xRel
= (xNow
< 0) ? -start
.x
: xRel
;
652 else if (xNow
> imgXRes
)
653 xRel
= imgXRes
-start
.x
;
655 yRel
= (yNow
< 0) ? -start
.y
: yRel
;
656 else if (yNow
> imgYRes
)
657 yRel
= imgYRes
-start
.y
;
659 /* rectsel and shape tools always show non-negative numbers when drawing */
660 if ((activeTool
== TOOL_RECTSEL
) || (activeTool
== TOOL_SHAPE
))
667 /* while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 */
677 _stprintf(coordStr
, _T("%d, %d"), xNow
, yNow
);
678 SendMessage(hStatusBar
, SB_SETTEXT
, 1, (LPARAM
) coordStr
);
682 if ((wParam
& MK_LBUTTON
) != 0)
684 whilePaintingL(hDrawingDC
, xNow
, yNow
, fgColor
, bgColor
);
685 InvalidateRect(hImageArea
, NULL
, FALSE
);
686 if ((activeTool
>= TOOL_TEXT
) || (activeTool
== TOOL_RECTSEL
) || (activeTool
== TOOL_FREESEL
))
689 if ((activeTool
>= TOOL_LINE
) && (GetAsyncKeyState(VK_SHIFT
) < 0))
691 _stprintf(sizeStr
, _T("%d x %d"), xRel
, yRel
);
692 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) sizeStr
);
695 if ((wParam
& MK_RBUTTON
) != 0)
697 whilePaintingR(hDrawingDC
, xNow
, yNow
, fgColor
, bgColor
);
698 InvalidateRect(hImageArea
, NULL
, FALSE
);
699 if (activeTool
>= TOOL_TEXT
)
702 if ((activeTool
>= TOOL_LINE
) && (GetAsyncKeyState(VK_SHIFT
) < 0))
704 _stprintf(sizeStr
, _T("%d x %d"), xRel
, yRel
);
705 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) sizeStr
);
713 SendMessage(hStatusBar
, SB_SETTEXT
, 1, (LPARAM
) _T(""));
714 if (activeTool
== TOOL_ZOOM
)
715 InvalidateRect(hImageArea
, NULL
, FALSE
);
718 // menu and button events
720 case WM_SYSCOLORCHANGE
:
722 /* Redirect message to common controls */
723 HWND hToolbar
= FindWindowEx(hToolBoxContainer
, NULL
, TOOLBARCLASSNAME
, NULL
);
724 SendMessage(hToolbar
, WM_SYSCOLORCHANGE
, 0, 0);
729 switch (LOWORD(wParam
))
733 HICON paintIcon
= LoadIcon(hProgInstance
, MAKEINTRESOURCE(IDI_APPICON
));
734 TCHAR infotitle
[100];
736 LoadString(hProgInstance
, IDS_INFOTITLE
, infotitle
, SIZEOF(infotitle
));
737 LoadString(hProgInstance
, IDS_INFOTEXT
, infotext
, SIZEOF(infotext
));
738 ShellAbout(hMainWnd
, infotitle
, infotext
, paintIcon
);
739 DeleteObject(paintIcon
);
742 case IDM_HELPHELPTOPICS
:
743 //HtmlHelp(hMainWnd, "help\\Paint.chm", 0, 0);
746 SendMessage(hwnd
, WM_CLOSE
, wParam
, lParam
);
753 TCHAR programname
[20];
754 TCHAR saveprompttext
[100];
756 LoadString(hProgInstance
, IDS_PROGRAMNAME
, programname
, SIZEOF(programname
));
757 LoadString(hProgInstance
, IDS_SAVEPROMPTTEXT
, saveprompttext
, SIZEOF(saveprompttext
));
758 _stprintf(temptext
, saveprompttext
, filename
);
759 switch (MessageBox(hwnd
, temptext
, programname
, MB_YESNOCANCEL
| MB_ICONQUESTION
))
772 if (reset
&& imageSaved
)
774 Rectangle(hDrawingDC
, 0 - 1, 0 - 1, imgXRes
+ 1, imgYRes
+ 1);
775 InvalidateRect(hImageArea
, NULL
, FALSE
);
776 updateCanvasAndScrollbars();
782 if (GetOpenFileName(&ofn
) != 0)
784 HBITMAP bmNew
= NULL
;
785 LoadDIBFromFile(&bmNew
, ofn
.lpstrFile
, &fileTime
, &fileSize
, &fileHPPM
, &fileVPPM
);
790 insertReversible(bmNew
);
791 updateCanvasAndScrollbars();
792 CopyMemory(filename
, ofn
.lpstrFileTitle
, sizeof(filename
));
793 CopyMemory(filepathname
, ofn
.lpstrFileTitle
, sizeof(filepathname
));
794 LoadString(hProgInstance
, IDS_WINDOWTITLE
, resstr
, SIZEOF(resstr
));
795 _stprintf(tempstr
, resstr
, filename
);
796 SetWindowText(hMainWnd
, tempstr
);
802 TCHAR programname
[20];
803 TCHAR loaderrortext
[100];
805 LoadString(hProgInstance
, IDS_PROGRAMNAME
, programname
, SIZEOF(programname
));
806 LoadString(hProgInstance
, IDS_LOADERRORTEXT
, loaderrortext
, SIZEOF(loaderrortext
));
807 _stprintf(temptext
, loaderrortext
, ofn
.lpstrFile
);
808 MessageBox(hwnd
, temptext
, programname
, MB_OK
| MB_ICONEXCLAMATION
);
818 case IDM_FILEASWALLPAPERPLANE
:
819 SetWallpaper(filepathname
, 1, 1);
821 case IDM_FILEASWALLPAPERCENTERED
:
822 SetWallpaper(filepathname
, 1, 0);
824 case IDM_FILEASWALLPAPERSTRETCHED
:
825 SetWallpaper(filepathname
, 2, 0);
829 InvalidateRect(hImageArea
, NULL
, FALSE
);
833 InvalidateRect(hImageArea
, NULL
, FALSE
);
836 OpenClipboard(hMainWnd
);
838 SetClipboardData(CF_BITMAP
, CopyImage(hSelBm
, IMAGE_BITMAP
, 0, 0, LR_COPYRETURNORG
));
843 SendMessage(hwnd
, WM_COMMAND
, IDM_EDITCOPY
, 0);
844 /* Delete selection */
845 SendMessage(hwnd
, WM_COMMAND
, IDM_EDITDELETESELECTION
, 0);
848 OpenClipboard(hMainWnd
);
849 if (GetClipboardData(CF_BITMAP
) != NULL
)
851 HWND hToolbar
= FindWindowEx(hToolBoxContainer
, NULL
, TOOLBARCLASSNAME
, NULL
);
852 SendMessage(hToolbar
, TB_CHECKBUTTON
, ID_RECTSEL
, MAKELONG(TRUE
, 0));
853 SendMessage(hwnd
, WM_COMMAND
, ID_RECTSEL
, 0);
855 DeleteObject(SelectObject(hSelDC
, hSelBm
= CopyImage(GetClipboardData(CF_BITMAP
),
859 rectSel_src
[0] = rectSel_src
[1] = rectSel_src
[2] = rectSel_src
[3] = 0;
860 rectSel_dest
[0] = rectSel_dest
[1] = 0;
861 rectSel_dest
[2] = GetDIBWidth(hSelBm
);
862 rectSel_dest
[3] = GetDIBHeight(hSelBm
);
863 BitBlt(hDrawingDC
, rectSel_dest
[0], rectSel_dest
[1], rectSel_dest
[2], rectSel_dest
[3],
864 hSelDC
, 0, 0, SRCCOPY
);
866 ShowWindow(hSelection
, SW_SHOW
);
870 case IDM_EDITDELETESELECTION
:
872 /* remove selection window and already painted content using undo(),
873 paint Rect for rectangular selections and Poly for freeform selections */
875 if (activeTool
== TOOL_RECTSEL
)
878 Rect(hDrawingDC
, rectSel_dest
[0], rectSel_dest
[1], rectSel_dest
[2] + rectSel_dest
[0],
879 rectSel_dest
[3] + rectSel_dest
[1], bgColor
, bgColor
, 0, TRUE
);
881 if (activeTool
== TOOL_FREESEL
)
884 Poly(hDrawingDC
, ptStack
, ptSP
+ 1, 0, 0, 2, 0, FALSE
);
888 case IDM_EDITSELECTALL
:
890 HWND hToolbar
= FindWindowEx(hToolBoxContainer
, NULL
, TOOLBARCLASSNAME
, NULL
);
891 SendMessage(hToolbar
, TB_CHECKBUTTON
, ID_RECTSEL
, MAKELONG(TRUE
, 0));
892 SendMessage(hwnd
, WM_COMMAND
, ID_RECTSEL
, 0);
893 startPaintingL(hDrawingDC
, 0, 0, fgColor
, bgColor
);
894 whilePaintingL(hDrawingDC
, imgXRes
, imgYRes
, fgColor
, bgColor
);
895 endPaintingL(hDrawingDC
, imgXRes
, imgYRes
, fgColor
, bgColor
);
899 if (GetSaveFileName(&ofn
) != 0)
900 SaveDIBToFile(hSelBm
, ofn
.lpstrFile
, hDrawingDC
, NULL
, NULL
, fileHPPM
, fileVPPM
);
902 case IDM_COLORSEDITPALETTE
:
903 if (ChooseColor(&choosecolor
))
905 fgColor
= choosecolor
.rgbResult
;
906 InvalidateRect(hPalWin
, NULL
, FALSE
);
909 case IDM_COLORSMODERNPALETTE
:
911 CopyMemory(palColors
, modernPalColors
, sizeof(palColors
));
912 InvalidateRect(hPalWin
, NULL
, FALSE
);
914 case IDM_COLORSOLDPALETTE
:
916 CopyMemory(palColors
, oldPalColors
, sizeof(palColors
));
917 InvalidateRect(hPalWin
, NULL
, FALSE
);
919 case IDM_IMAGEINVERTCOLORS
:
923 SetRect(&tempRect
, 0, 0, imgXRes
, imgYRes
);
924 InvertRect(hDrawingDC
, &tempRect
);
925 InvalidateRect(hImageArea
, NULL
, FALSE
);
928 case IDM_IMAGEDELETEIMAGE
:
930 Rect(hDrawingDC
, 0, 0, imgXRes
, imgYRes
, bgColor
, bgColor
, 0, TRUE
);
931 InvalidateRect(hImageArea
, NULL
, FALSE
);
933 case IDM_IMAGEROTATEMIRROR
:
934 switch (mirrorRotateDlg())
936 case 1: /* flip horizontally */
937 if (IsWindowVisible(hSelection
))
939 SelectObject(hSelDC
, hSelMask
);
940 StretchBlt(hSelDC
, rectSel_dest
[2] - 1, 0, -rectSel_dest
[2], rectSel_dest
[3], hSelDC
,
941 0, 0, rectSel_dest
[2], rectSel_dest
[3], SRCCOPY
);
942 SelectObject(hSelDC
, hSelBm
);
943 StretchBlt(hSelDC
, rectSel_dest
[2] - 1, 0, -rectSel_dest
[2], rectSel_dest
[3], hSelDC
,
944 0, 0, rectSel_dest
[2], rectSel_dest
[3], SRCCOPY
);
945 /* force refresh of selection contents, used also in case 2 and case 4 */
946 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, 0);
947 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, 0);
948 SendMessage(hSelection
, WM_LBUTTONUP
, 0, 0);
953 StretchBlt(hDrawingDC
, imgXRes
- 1, 0, -imgXRes
, imgYRes
, hDrawingDC
, 0, 0,
954 imgXRes
, imgYRes
, SRCCOPY
);
955 InvalidateRect(hImageArea
, NULL
, FALSE
);
958 case 2: /* flip vertically */
959 if (IsWindowVisible(hSelection
))
961 SelectObject(hSelDC
, hSelMask
);
962 StretchBlt(hSelDC
, 0, rectSel_dest
[3] - 1, rectSel_dest
[2], -rectSel_dest
[3], hSelDC
,
963 0, 0, rectSel_dest
[2], rectSel_dest
[3], SRCCOPY
);
964 SelectObject(hSelDC
, hSelBm
);
965 StretchBlt(hSelDC
, 0, rectSel_dest
[3] - 1, rectSel_dest
[2], -rectSel_dest
[3], hSelDC
,
966 0, 0, rectSel_dest
[2], rectSel_dest
[3], SRCCOPY
);
967 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, 0);
968 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, 0);
969 SendMessage(hSelection
, WM_LBUTTONUP
, 0, 0);
974 StretchBlt(hDrawingDC
, 0, imgYRes
- 1, imgXRes
, -imgYRes
, hDrawingDC
, 0, 0,
975 imgXRes
, imgYRes
, SRCCOPY
);
976 InvalidateRect(hImageArea
, NULL
, FALSE
);
979 case 3: /* rotate 90 degrees */
981 case 4: /* rotate 180 degrees */
982 if (IsWindowVisible(hSelection
))
984 SelectObject(hSelDC
, hSelMask
);
985 StretchBlt(hSelDC
, rectSel_dest
[2] - 1, rectSel_dest
[3] - 1, -rectSel_dest
[2], -rectSel_dest
[3], hSelDC
,
986 0, 0, rectSel_dest
[2], rectSel_dest
[3], SRCCOPY
);
987 SelectObject(hSelDC
, hSelBm
);
988 StretchBlt(hSelDC
, rectSel_dest
[2] - 1, rectSel_dest
[3] - 1, -rectSel_dest
[2], -rectSel_dest
[3], hSelDC
,
989 0, 0, rectSel_dest
[2], rectSel_dest
[3], SRCCOPY
);
990 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, 0);
991 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, 0);
992 SendMessage(hSelection
, WM_LBUTTONUP
, 0, 0);
997 StretchBlt(hDrawingDC
, imgXRes
- 1, imgYRes
- 1, -imgXRes
, -imgYRes
, hDrawingDC
,
998 0, 0, imgXRes
, imgYRes
, SRCCOPY
);
999 InvalidateRect(hImageArea
, NULL
, FALSE
);
1002 case 5: /* rotate 270 degrees */
1006 case IDM_IMAGEATTRIBUTES
:
1008 if (attributesDlg())
1010 cropReversible(widthSetInDlg
, heightSetInDlg
, 0, 0);
1011 updateCanvasAndScrollbars();
1015 case IDM_IMAGESTRETCHSKEW
:
1017 if (changeSizeDlg())
1019 insertReversible(CopyImage(hBms
[currInd
], IMAGE_BITMAP
,
1020 imgXRes
* stretchSkew
.percentage
.x
/ 100,
1021 imgYRes
* stretchSkew
.percentage
.y
/ 100, 0));
1022 updateCanvasAndScrollbars();
1026 case IDM_IMAGEDRAWOPAQUE
:
1027 transpBg
= 1 - transpBg
;
1028 InvalidateRect(hToolSettings
, NULL
, TRUE
);
1031 insertReversible(CopyImage(hSelBm
, IMAGE_BITMAP
, 0, 0, LR_COPYRETURNORG
));
1032 updateCanvasAndScrollbars();
1035 case IDM_VIEWTOOLBOX
:
1036 ShowWindow(hToolBoxContainer
, IsWindowVisible(hToolBoxContainer
) ? SW_HIDE
: SW_SHOW
);
1037 alignChildrenToMainWindow();
1039 case IDM_VIEWCOLORPALETTE
:
1040 ShowWindow(hPalWin
, IsWindowVisible(hPalWin
) ? SW_HIDE
: SW_SHOW
);
1041 alignChildrenToMainWindow();
1043 case IDM_VIEWSTATUSBAR
:
1044 ShowWindow(hStatusBar
, IsWindowVisible(hStatusBar
) ? SW_HIDE
: SW_SHOW
);
1045 alignChildrenToMainWindow();
1048 case IDM_VIEWSHOWGRID
:
1049 showGrid
= !showGrid
;
1050 InvalidateRect(hImageArea
, NULL
, FALSE
);
1052 case IDM_VIEWSHOWMINIATURE
:
1053 showMiniature
= !showMiniature
;
1054 ShowWindow(hwndMiniature
, showMiniature
? SW_SHOW
: SW_HIDE
);
1057 case IDM_VIEWZOOM125
:
1060 case IDM_VIEWZOOM25
:
1063 case IDM_VIEWZOOM50
:
1066 case IDM_VIEWZOOM100
:
1069 case IDM_VIEWZOOM200
:
1072 case IDM_VIEWZOOM400
:
1075 case IDM_VIEWZOOM800
:
1129 return DefWindowProc(hwnd
, message
, wParam
, lParam
);