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 /* FUNCTIONS ********************************************************/
15 LPCTSTR cursors
[9] = { IDC_SIZEALL
, IDC_SIZENWSE
, IDC_SIZENS
, IDC_SIZENESW
,
16 IDC_SIZEWE
, IDC_SIZEWE
, IDC_SIZENESW
, IDC_SIZENS
, IDC_SIZENWSE
26 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
)
34 hTempDC
= CreateCompatibleDC(hdcSrc
);
35 hTempDC2
= CreateCompatibleDC(hdcSrc
);
36 hTempBm
= CreateCompatibleBitmap(hTempDC
, nWidth
, nHeight
);
37 SelectObject(hTempDC
, hTempBm
);
38 hTempBrush
= CreateSolidBrush(keyColor
);
39 SelectObject(hTempDC
, hTempBrush
);
40 BitBlt(hTempDC
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, SRCCOPY
);
41 PatBlt(hTempDC
, 0, 0, nWidth
, nHeight
, PATINVERT
);
42 hTempMask
= CreateBitmap(nWidth
, nHeight
, 1, 1, NULL
);
43 SelectObject(hTempDC2
, hTempMask
);
44 BitBlt(hTempDC2
, 0, 0, nWidth
, nHeight
, hTempDC
, 0, 0, SRCCOPY
);
45 SelectObject(hTempDC
, hbmMask
);
46 BitBlt(hTempDC2
, 0, 0, nWidth
, nHeight
, hTempDC
, xMask
, yMask
, SRCAND
);
47 MaskBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, hTempMask
, xMask
, yMask
, dwRop
);
50 DeleteObject(hTempBm
);
51 DeleteObject(hTempBrush
);
52 DeleteObject(hTempMask
);
57 ForceRefreshSelectionContents()
59 if (IsWindowVisible(hSelection
))
61 SendMessage(hSelection
, WM_LBUTTONDOWN
, 0, MAKELPARAM(0, 0));
62 SendMessage(hSelection
, WM_MOUSEMOVE
, 0, MAKELPARAM(0, 0));
63 SendMessage(hSelection
, WM_LBUTTONUP
, 0, MAKELPARAM(0, 0));
68 identifyCorner(short x
, short y
, short w
, short h
)
74 if ((x
< w
/ 2 + 2) && (x
>= w
/ 2 - 1))
79 if ((y
< h
/ 2 + 2) && (y
>= h
/ 2 - 1))
90 if ((x
< w
/ 2 + 2) && (x
>= w
/ 2 - 1))
99 SelectionWinProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
107 HDC hDC
= GetDC(hwnd
);
108 DefWindowProc(hwnd
, message
, wParam
, lParam
);
109 SelectionFrame(hDC
, 1, 1, RECT_WIDTH(rectSel_dest
) * zoom
/ 1000 + 5,
110 RECT_HEIGHT(rectSel_dest
) * zoom
/ 1000 + 5);
111 ReleaseDC(hwnd
, hDC
);
116 pos
.x
= GET_X_LPARAM(lParam
);
117 pos
.y
= GET_Y_LPARAM(lParam
);
122 SetCursor(LoadCursor(NULL
, cursors
[action
]));
131 frac
.x
+= GET_X_LPARAM(lParam
) - pos
.x
;
132 frac
.y
+= GET_Y_LPARAM(lParam
) - pos
.y
;
133 delta
.x
+= frac
.x
* 1000 / zoom
;
134 delta
.y
+= frac
.y
* 1000 / zoom
;
142 frac
.x
-= (frac
.x
* 1000 / zoom
) * zoom
/ 1000;
143 frac
.y
-= (frac
.y
* 1000 / zoom
) * zoom
/ 1000;
147 case 0: /* move selection */
148 deltaUsed
.x
= delta
.x
;
149 deltaUsed
.y
= delta
.y
;
150 OffsetRect(&rectSel_dest
, deltaUsed
.x
, deltaUsed
.y
);
152 case 1: /* resize at upper left corner */
153 deltaUsed
.x
= min(delta
.x
, RECT_WIDTH(rectSel_dest
) - 1);
154 deltaUsed
.y
= min(delta
.y
, RECT_HEIGHT(rectSel_dest
) - 1);
155 rectSel_dest
.left
+= deltaUsed
.x
;
156 rectSel_dest
.top
+= deltaUsed
.y
;
158 case 2: /* resize at top edge */
159 deltaUsed
.x
= delta
.x
;
160 deltaUsed
.y
= min(delta
.y
, RECT_HEIGHT(rectSel_dest
) - 1);
161 rectSel_dest
.top
+= deltaUsed
.y
;
163 case 3: /* resize at upper right corner */
164 deltaUsed
.x
= max(delta
.x
, -(RECT_WIDTH(rectSel_dest
) - 1));
165 deltaUsed
.y
= min(delta
.y
, RECT_HEIGHT(rectSel_dest
) - 1);
166 rectSel_dest
.top
+= deltaUsed
.y
;
167 rectSel_dest
.right
+= deltaUsed
.x
;
169 case 4: /* resize at left edge */
170 deltaUsed
.x
= min(delta
.x
, RECT_WIDTH(rectSel_dest
) - 1);
171 deltaUsed
.y
= delta
.y
;
172 rectSel_dest
.left
+= deltaUsed
.x
;
174 case 5: /* resize at right edge */
175 deltaUsed
.x
= max(delta
.x
, -(RECT_WIDTH(rectSel_dest
) - 1));
176 deltaUsed
.y
= delta
.y
;
177 rectSel_dest
.right
+= deltaUsed
.x
;
179 case 6: /* resize at lower left corner */
180 deltaUsed
.x
= min(delta
.x
, RECT_WIDTH(rectSel_dest
) - 1);
181 deltaUsed
.y
= max(delta
.y
, -(RECT_HEIGHT(rectSel_dest
) - 1));
182 rectSel_dest
.left
+= deltaUsed
.x
;
183 rectSel_dest
.bottom
+= deltaUsed
.y
;
185 case 7: /* resize at bottom edge */
186 deltaUsed
.x
= delta
.x
;
187 deltaUsed
.y
= max(delta
.y
, -(RECT_HEIGHT(rectSel_dest
) - 1));
188 rectSel_dest
.bottom
+= deltaUsed
.y
;
190 case 8: /* resize at lower right corner */
191 deltaUsed
.x
= max(delta
.x
, -(RECT_WIDTH(rectSel_dest
) - 1));
192 deltaUsed
.y
= max(delta
.y
, -(RECT_HEIGHT(rectSel_dest
) - 1));
193 rectSel_dest
.right
+= deltaUsed
.x
;
194 rectSel_dest
.bottom
+= deltaUsed
.y
;
197 delta
.x
-= deltaUsed
.x
;
198 delta
.y
-= deltaUsed
.y
;
200 _stprintf(sizeStr
, _T("%d x %d"), RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
));
201 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) sizeStr
);
203 if (activeTool
== 10) /* text tool */
205 Text(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, rectSel_dest
.right
, rectSel_dest
.bottom
, fgColor
, bgColor
, textToolText
, hfontTextFont
, transpBg
);
210 StretchBlt(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), hSelDC
, 0, 0, GetDIBWidth(hSelBm
), GetDIBHeight(hSelBm
), SRCCOPY
);
213 MaskBlt(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
),
214 hSelDC
, 0, 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
));
217 ColorKeyedMaskBlt(hDrawingDC
, rectSel_dest
.left
, rectSel_dest
.top
, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
),
218 hSelDC
, 0, 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
), bgColor
);
221 InvalidateRect(hImageArea
, NULL
, FALSE
);
222 pos
.x
= GET_X_LPARAM(lParam
);
223 pos
.y
= GET_Y_LPARAM(lParam
);
224 //SendMessage(hwnd, WM_PAINT, 0, 0);
228 int w
= RECT_WIDTH(rectSel_dest
) * zoom
/ 1000 + 6;
229 int h
= RECT_HEIGHT(rectSel_dest
) * zoom
/ 1000 + 6;
230 pos
.x
= GET_X_LPARAM(lParam
);
231 pos
.y
= GET_Y_LPARAM(lParam
);
232 SendMessage(hStatusBar
, SB_SETTEXT
, 2, (LPARAM
) NULL
);
233 action
= identifyCorner(pos
.x
, pos
.y
, w
, h
);
235 SetCursor(LoadCursor(NULL
, cursors
[action
]));
245 if (activeTool
== 10) /* text tool */
253 hTempDC
= CreateCompatibleDC(hSelDC
);
254 hTempBm
= CreateDIBWithProperties(RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
));
255 SelectObject(hTempDC
, hTempBm
);
256 SelectObject(hSelDC
, hSelBm
);
257 StretchBlt(hTempDC
, 0, 0, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), hSelDC
, 0, 0,
258 GetDIBWidth(hSelBm
), GetDIBHeight(hSelBm
), SRCCOPY
);
259 DeleteObject(hSelBm
);
261 hTempBm
= CreateBitmap(RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), 1, 1, NULL
);
262 SelectObject(hTempDC
, hTempBm
);
263 SelectObject(hSelDC
, hSelMask
);
264 StretchBlt(hTempDC
, 0, 0, RECT_WIDTH(rectSel_dest
), RECT_HEIGHT(rectSel_dest
), hSelDC
, 0, 0,
265 GetDIBWidth(hSelMask
), GetDIBHeight(hSelMask
), SRCCOPY
);
266 DeleteObject(hSelMask
);
268 SelectObject(hSelDC
, hSelBm
);
273 ShowWindow(hSelection
, SW_HIDE
);
274 ShowWindow(hSelection
, SW_SHOW
);
278 return DefWindowProc(hwnd
, message
, wParam
, lParam
);