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