- Update to r53061
[reactos.git] / base / applications / mspaint / selection.c
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/paint/selection.c
5 * PURPOSE: Window procedure of the selection window
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include "precomp.h"
12
13 /* FUNCTIONS ********************************************************/
14
15 LPCTSTR cursors[9] = { IDC_SIZEALL, IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
16 IDC_SIZEWE, IDC_SIZEWE, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
17 };
18
19 BOOL moving = FALSE;
20 int action = 0;
21 short xPos;
22 short yPos;
23 short xFrac;
24 short yFrac;
25
26 int
27 identifyCorner(short x, short y, short w, short h)
28 {
29 if (y < 3)
30 {
31 if (x < 3)
32 return 1;
33 if ((x < w / 2 + 2) && (x >= w / 2 - 1))
34 return 2;
35 if (x >= w - 3)
36 return 3;
37 }
38 if ((y < h / 2 + 2) && (y >= h / 2 - 1))
39 {
40 if (x < 3)
41 return 4;
42 if (x >= w - 3)
43 return 5;
44 }
45 if (y >= h - 3)
46 {
47 if (x < 3)
48 return 6;
49 if ((x < w / 2 + 2) && (x >= w / 2 - 1))
50 return 7;
51 if (x >= w - 3)
52 return 8;
53 }
54 return 0;
55 }
56
57 LRESULT CALLBACK
58 SelectionWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
59 {
60 switch (message)
61 {
62 case WM_PAINT:
63 {
64 if (!moving)
65 {
66 HDC hDC = GetDC(hwnd);
67 DefWindowProc(hwnd, message, wParam, lParam);
68 SelectionFrame(hDC, 1, 1, rectSel_dest[2] * zoom / 1000 + 5,
69 rectSel_dest[3] * zoom / 1000 + 5);
70 ReleaseDC(hwnd, hDC);
71 }
72 break;
73 }
74 case WM_LBUTTONDOWN:
75 xPos = LOWORD(lParam);
76 yPos = HIWORD(lParam);
77 SetCapture(hwnd);
78 if (action != 0)
79 SetCursor(LoadCursor(NULL, cursors[action]));
80 moving = TRUE;
81 break;
82 case WM_MOUSEMOVE:
83 if (moving)
84 {
85 TCHAR sizeStr[100];
86 int xDelta;
87 int yDelta;
88 resetToU1();
89 xFrac += (short)LOWORD(lParam) - xPos;
90 yFrac += (short)HIWORD(lParam) - yPos;
91 if (zoom < 1000)
92 {
93 xDelta = xFrac * 1000 / zoom;
94 xFrac = 0;
95 yDelta = yFrac * 1000 / zoom;
96 yFrac = 0;
97 }
98 else
99 {
100 xDelta = xFrac * 1000 / zoom;
101 xFrac -= (xFrac * 1000 / zoom) * zoom / 1000;
102 yDelta = yFrac * 1000 / zoom;
103 yFrac -= (yFrac * 1000 / zoom) * zoom / 1000;
104 }
105 switch (action)
106 {
107 case 0:
108 rectSel_dest[0] += xDelta;
109 rectSel_dest[1] += yDelta;
110 break;
111 case 1:
112 rectSel_dest[0] += xDelta;
113 rectSel_dest[1] += yDelta;
114 rectSel_dest[2] -= xDelta;
115 rectSel_dest[3] -= yDelta;
116 break;
117 case 2:
118 rectSel_dest[1] += yDelta;
119 rectSel_dest[3] -= yDelta;
120 break;
121 case 3:
122 rectSel_dest[2] += xDelta;
123 rectSel_dest[1] += yDelta;
124 break;
125 case 4:
126 rectSel_dest[0] += xDelta;
127 rectSel_dest[2] -= xDelta;
128 break;
129 case 5:
130 rectSel_dest[2] += xDelta;
131 break;
132 case 6:
133 rectSel_dest[0] += xDelta;
134 rectSel_dest[2] -= xDelta;
135 rectSel_dest[3] += yDelta;
136 break;
137 case 7:
138 rectSel_dest[3] += yDelta;
139 break;
140 case 8:
141 rectSel_dest[2] += xDelta;
142 rectSel_dest[3] += yDelta;
143 break;
144 }
145
146 _stprintf(sizeStr, _T("%d x %d"), rectSel_dest[2], rectSel_dest[3]);
147 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
148
149 if (action != 0)
150 StretchBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0, GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY);
151 else
152 if (transpBg == 0)
153 MaskBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
154 hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
155 else
156 {
157 HBITMAP tempMask;
158 HBRUSH oldBrush;
159 HDC tempDC;
160 tempMask = CreateBitmap(rectSel_dest[2], rectSel_dest[3], 1, 1, NULL);
161 oldBrush = SelectObject(hSelDC, CreateSolidBrush(bgColor));
162 tempDC = CreateCompatibleDC(hSelDC);
163 SelectObject(tempDC, tempMask);
164 MaskBlt(tempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0, hSelMask, 0, 0,
165 MAKEROP4(NOTSRCCOPY, BLACKNESS));
166 DeleteDC(tempDC);
167 DeleteObject(SelectObject(hSelDC, oldBrush));
168
169 MaskBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
170 hSelDC, 0, 0, tempMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
171 DeleteObject(tempMask);
172 }
173 SendMessage(hImageArea, WM_PAINT, 0, 0);
174 xPos = LOWORD(lParam);
175 yPos = HIWORD(lParam);
176 //SendMessage(hwnd, WM_PAINT, 0, 0);
177 }
178 else
179 {
180 int w = rectSel_dest[2] * zoom / 1000 + 6;
181 int h = rectSel_dest[3] * zoom / 1000 + 6;
182 xPos = LOWORD(lParam);
183 yPos = HIWORD(lParam);
184 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) NULL);
185 action = identifyCorner(xPos, yPos, w, h);
186 if (action != 0)
187 SetCursor(LoadCursor(NULL, cursors[action]));
188 }
189 break;
190 case WM_LBUTTONUP:
191 if (moving)
192 {
193 moving = FALSE;
194 ReleaseCapture();
195 if (action != 0)
196 {
197 HDC hTempDC;
198 HBITMAP hTempBm;
199 hTempDC = CreateCompatibleDC(hSelDC);
200 hTempBm = CreateDIBWithProperties(rectSel_dest[2], rectSel_dest[3]);
201 SelectObject(hTempDC, hTempBm);
202 SelectObject(hSelDC, hSelBm);
203 StretchBlt(hTempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0,
204 GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY);
205 DeleteObject(hSelBm);
206 hSelBm = hTempBm;
207 hTempBm = CreateBitmap(rectSel_dest[2], rectSel_dest[3], 1, 1, NULL);
208 SelectObject(hTempDC, hTempBm);
209 SelectObject(hSelDC, hSelMask);
210 StretchBlt(hTempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0,
211 GetDIBWidth(hSelMask), GetDIBHeight(hSelMask), SRCCOPY);
212 DeleteObject(hSelMask);
213 hSelMask = hTempBm;
214 SelectObject(hSelDC, hSelBm);
215 DeleteDC(hTempDC);
216 }
217 placeSelWin();
218 ShowWindow(hSelection, SW_HIDE);
219 ShowWindow(hSelection, SW_SHOW);
220 }
221 break;
222 default:
223 return DefWindowProc(hwnd, message, wParam, lParam);
224 }
225
226 return 0;
227 }