2 * PROJECT: PAINT for ReactOS
4 * FILE: base/applications/paint/selection.c
5 * PURPOSE: Window procedure of the selection window
6 * PROGRAMMERS: Benedikt Freisen
9 /* INCLUDES *********************************************************/
13 /* DEFINES **********************************************************/
16 #define ACTION_RESIZE_TOP_LEFT 1
17 #define ACTION_RESIZE_TOP 2
18 #define ACTION_RESIZE_TOP_RIGHT 3
19 #define ACTION_RESIZE_LEFT 4
20 #define ACTION_RESIZE_RIGHT 5
21 #define ACTION_RESIZE_BOTTOM_LEFT 6
22 #define ACTION_RESIZE_BOTTOM 7
23 #define ACTION_RESIZE_BOTTOM_RIGHT 8
25 /* FUNCTIONS ********************************************************/
27 LPCTSTR cursors
[9] = { /* action to mouse cursor lookup table */
30 IDC_SIZENWSE
, IDC_SIZENS
, IDC_SIZENESW
,
31 IDC_SIZEWE
, IDC_SIZEWE
,
32 IDC_SIZENESW
, IDC_SIZENS
, IDC_SIZENWSE
36 int action
= ACTION_MOVE
;
42 RegisterWclSelection()
44 WNDCLASSEX wclSelection
;
45 /* initializing and registering the window class for the selection frame */
46 wclSelection
.hInstance
= hProgInstance
;
47 wclSelection
.lpszClassName
= _T("Selection");
48 wclSelection
.lpfnWndProc
= SelectionWinProc
;
49 wclSelection
.style
= CS_DBLCLKS
;
50 wclSelection
.cbSize
= sizeof(WNDCLASSEX
);
51 wclSelection
.hIcon
= NULL
;
52 wclSelection
.hIconSm
= NULL
;
53 wclSelection
.hCursor
= LoadCursor(NULL
, IDC_SIZEALL
);
54 wclSelection
.lpszMenuName
= NULL
;
55 wclSelection
.cbClsExtra
= 0;
56 wclSelection
.cbWndExtra
= 0;
57 wclSelection
.hbrBackground
= NULL
;
58 RegisterClassEx (&wclSelection
);
62 ColorKeyedMaskBlt(HDC hdcDest
, int nXDest
, int nYDest
, int nWidth
, int nHeight
, HDC hdcSrc
, int nXSrc
, int nYSrc
, HBITMAP hbmMask
, int xMask
, int yMask
, DWORD dwRop
, COLORREF keyColor
)
70 hTempDC
= CreateCompatibleDC(hdcSrc
);
71 hTempDC2
= CreateCompatibleDC(hdcSrc
);
72 hTempBm
= CreateCompatibleBitmap(hTempDC
, nWidth
, nHeight
);
73 SelectObject(hTempDC
, hTempBm
);
74 hTempBrush
= CreateSolidBrush(keyColor
);
75 SelectObject(hTempDC
, hTempBrush
);
76 BitBlt(hTempDC
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, SRCCOPY
);
77 PatBlt(hTempDC
, 0, 0, nWidth
, nHeight
, PATINVERT
);
78 hTempMask
= CreateBitmap(nWidth
, nHeight
, 1, 1, NULL
);
79 SelectObject(hTempDC2
, hTempMask
);
80 BitBlt(hTempDC2
, 0, 0, nWidth
, nHeight
, hTempDC
, 0, 0, SRCCOPY
);
81 SelectObject(hTempDC
, hbmMask
);
82 BitBlt(hTempDC2
, 0, 0, nWidth
, nHeight
, hTempDC
, xMask
, yMask
, SRCAND
);
83 MaskBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, hTempMask
, xMask
, yMask
, dwRop
);
86 DeleteObject(hTempBm
);
87 DeleteObject(hTempBrush
);
88 DeleteObject(hTempMask
);
93 ForceRefreshSelectionContents()
95 if (IsWindowVisible(hSelection
))
97 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, MAKELPARAM(0, 0));
98 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, MAKELPARAM(0, 0));
99 SendMessage(hSelection
, WM_LBUTTONUP
, 0, MAKELPARAM(0, 0));
104 identifyCorner(short x
, short y
, short w
, short h
)
109 return ACTION_RESIZE_TOP_LEFT
;
110 if ((x
< w
/ 2 + 2) && (x
>= w
/ 2 - 1))
111 return ACTION_RESIZE_TOP
;
113 return ACTION_RESIZE_TOP_RIGHT
;
115 if ((y
< h
/ 2 + 2) && (y
>= h
/ 2 - 1))
118 return ACTION_RESIZE_LEFT
;
120 return ACTION_RESIZE_RIGHT
;
125 return ACTION_RESIZE_BOTTOM_LEFT
;
126 if ((x
< w
/ 2 + 2) && (x
>= w
/ 2 - 1))
127 return ACTION_RESIZE_BOTTOM
;
129 return ACTION_RESIZE_BOTTOM_RIGHT
;
135 SelectionWinProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
143 HDC hDC
= GetDC(hwnd
);
144 DefWindowProc(hwnd
, message
, wParam
, lParam
);
145 SelectionFrame(hDC
, 1, 1, RECT_WIDTH(rectSel_dest
) * zoom
/ 1000 + 5,
146 RECT_HEIGHT(rectSel_dest
) * zoom
/ 1000 + 5);
147 ReleaseDC(hwnd
, hDC
);
152 pos
.x
= GET_X_LPARAM(lParam
);
153 pos
.y
= GET_Y_LPARAM(lParam
);
157 if (action
!= ACTION_MOVE
)
158 SetCursor(LoadCursor(NULL
, cursors
[action
]));
160 InvalidateRect(hScrlClient
, NULL
, TRUE
);
168 frac
.x
+= GET_X_LPARAM(lParam
) - pos
.x
;
169 frac
.y
+= GET_Y_LPARAM(lParam
) - pos
.y
;
170 delta
.x
+= frac
.x
* 1000 / zoom
;
171 delta
.y
+= frac
.y
* 1000 / zoom
;
179 frac
.x
-= (frac
.x
* 1000 / zoom
) * zoom
/ 1000;
180 frac
.y
-= (frac
.y
* 1000 / zoom
) * zoom
/ 1000;
184 case ACTION_MOVE
: /* move selection */
185 deltaUsed
.x
= delta
.x
;
186 deltaUsed
.y
= delta
.y
;
187 OffsetRect(&rectSel_dest
, deltaUsed
.x
, deltaUsed
.y
);
189 case ACTION_RESIZE_TOP_LEFT
: /* resize at upper left corner */
190 deltaUsed
.x
= min(delta
.x
, RECT_WIDTH(rectSel_dest
) - 1);
191 deltaUsed
.y
= min(delta
.y
, RECT_HEIGHT(rectSel_dest
) - 1);
192 rectSel_dest
.left
+= deltaUsed
.x
;
193 rectSel_dest
.top
+= deltaUsed
.y
;
195 case ACTION_RESIZE_TOP
: /* resize at top edge */
196 deltaUsed
.x
= delta
.x
;
197 deltaUsed
.y
= min(delta
.y
, RECT_HEIGHT(rectSel_dest
) - 1);
198 rectSel_dest
.top
+= deltaUsed
.y
;
200 case ACTION_RESIZE_TOP_RIGHT
: /* resize at upper right corner */
201 deltaUsed
.x
= max(delta
.x
, -(RECT_WIDTH(rectSel_dest
) - 1));
202 deltaUsed
.y
= min(delta
.y
, RECT_HEIGHT(rectSel_dest
) - 1);
203 rectSel_dest
.top
+= deltaUsed
.y
;
204 rectSel_dest
.right
+= deltaUsed
.x
;
206 case ACTION_RESIZE_LEFT
: /* resize at left edge */
207 deltaUsed
.x
= min(delta
.x
, RECT_WIDTH(rectSel_dest
) - 1);
208 deltaUsed
.y
= delta
.y
;
209 rectSel_dest
.left
+= deltaUsed
.x
;
211 case ACTION_RESIZE_RIGHT
: /* resize at right edge */
212 deltaUsed
.x
= max(delta
.x
, -(RECT_WIDTH(rectSel_dest
) - 1));
213 deltaUsed
.y
= delta
.y
;
214 rectSel_dest
.right
+= deltaUsed
.x
;
216 case ACTION_RESIZE_BOTTOM_LEFT
: /* resize at lower left corner */
217 deltaUsed
.x
= min(delta
.x
, RECT_WIDTH(rectSel_dest
) - 1);
218 deltaUsed
.y
= max(delta
.y
, -(RECT_HEIGHT(rectSel_dest
) - 1));
219 rectSel_dest
.left
+= deltaUsed
.x
;
220 rectSel_dest
.bottom
+= deltaUsed
.y
;
222 case ACTION_RESIZE_BOTTOM
: /* resize at bottom edge */
223 deltaUsed
.x
= delta
.x
;
224 deltaUsed
.y
= max(delta
.y
, -(RECT_HEIGHT(rectSel_dest
) - 1));
225 rectSel_dest
.bottom
+= deltaUsed
.y
;
227 case ACTION_RESIZE_BOTTOM_RIGHT
: /* resize at lower right corner */
228 deltaUsed
.x
= max(delta
.x
, -(RECT_WIDTH(rectSel_dest
) - 1));
229 deltaUsed
.y
= max(delta
.y
, -(RECT_HEIGHT(rectSel_dest
) - 1));
230 rectSel_dest
.right
+= deltaUsed
.x
;
231 rectSel_dest
.bottom
+= deltaUsed
.y
;
234 delta
.x
-= deltaUsed
.x
;
235 delta
.y
-= deltaUsed
.y
;
237 _stprintf(sizeStr
, _T("%d x %d"), RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
));
238 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) sizeStr
);
240 if (activeTool
== TOOL_TEXT
)
242 Text(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, rectSel_dest
.right
, rectSel_dest
.bottom
, fgColor
, bgColor
, textToolText
, hfontTextFont
, transpBg
);
246 if (action
!= ACTION_MOVE
)
247 StretchBlt(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), hSelDC
, 0, 0, GetDIBWidth(hSelBm
), GetDIBHeight(hSelBm
), SRCCOPY
);
250 MaskBlt(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
),
251 hSelDC
, 0, 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
));
254 ColorKeyedMaskBlt(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
),
255 hSelDC
, 0, 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
), bgColor
);
258 InvalidateRect(hImageArea
, NULL
, FALSE
);
259 pos
.x
= GET_X_LPARAM(lParam
);
260 pos
.y
= GET_Y_LPARAM(lParam
);
264 int w
= RECT_WIDTH(rectSel_dest
) * zoom
/ 1000 + 6;
265 int h
= RECT_HEIGHT(rectSel_dest
) * zoom
/ 1000 + 6;
266 pos
.x
= GET_X_LPARAM(lParam
);
267 pos
.y
= GET_Y_LPARAM(lParam
);
268 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) NULL
);
269 action
= identifyCorner(pos
.x
, pos
.y
, w
, h
);
270 if (action
!= ACTION_MOVE
)
271 SetCursor(LoadCursor(NULL
, cursors
[action
]));
279 if (action
!= ACTION_MOVE
)
281 if (activeTool
== TOOL_TEXT
)
289 hTempDC
= CreateCompatibleDC(hSelDC
);
290 hTempBm
= CreateDIBWithProperties(RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
));
291 SelectObject(hTempDC
, hTempBm
);
292 SelectObject(hSelDC
, hSelBm
);
293 StretchBlt(hTempDC
, 0, 0, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), hSelDC
, 0, 0,
294 GetDIBWidth(hSelBm
), GetDIBHeight(hSelBm
), SRCCOPY
);
295 DeleteObject(hSelBm
);
297 hTempBm
= CreateBitmap(RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), 1, 1, NULL
);
298 SelectObject(hTempDC
, hTempBm
);
299 SelectObject(hSelDC
, hSelMask
);
300 StretchBlt(hTempDC
, 0, 0, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), hSelDC
, 0, 0,
301 GetDIBWidth(hSelMask
), GetDIBHeight(hSelMask
), SRCCOPY
);
302 DeleteObject(hSelMask
);
304 SelectObject(hSelDC
, hSelBm
);
309 ShowWindow(hSelection
, SW_HIDE
);
310 ShowWindow(hSelection
, SW_SHOW
);
314 return DefWindowProc(hwnd
, message
, wParam
, lParam
);