1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Window procedure of the size boxes
5 * COPYRIGHT: Copyright 2015 Benedikt Freisen <b.freisen@gmx.net>
6 * Copyright 2017 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 */
8
9 #include "precomp.h"
10
11 static LPCWSTR s_cursor_shapes[] =
12 {
13 IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
14 IDC_SIZEWE, IDC_SIZEWE,
15 IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE,
16 };
17
18 /* FUNCTIONS ********************************************************/
19
setCursorOnSizeBox(HITTEST hit)20 BOOL setCursorOnSizeBox(HITTEST hit)
21 {
22 if (HIT_UPPER_LEFT <= hit && hit <= HIT_LOWER_RIGHT)
23 {
24 ::SetCursor(::LoadCursorW(NULL, s_cursor_shapes[hit - HIT_UPPER_LEFT]));
25 return TRUE;
26 }
27 return FALSE;
28 }
29
getSizeBoxRect(LPRECT prc,HITTEST hit,LPCRECT prcBase)30 BOOL getSizeBoxRect(LPRECT prc, HITTEST hit, LPCRECT prcBase)
31 {
32 switch (hit)
33 {
34 case HIT_UPPER_LEFT:
35 prc->left = prcBase->left;
36 prc->top = prcBase->top;
37 break;
38 case HIT_UPPER_CENTER:
39 prc->left = (prcBase->left + prcBase->right - GRIP_SIZE) / 2;
40 prc->top = prcBase->top;
41 break;
42 case HIT_UPPER_RIGHT:
43 prc->left = prcBase->right - GRIP_SIZE;
44 prc->top = prcBase->top;
45 break;
46 case HIT_MIDDLE_LEFT:
47 prc->left = prcBase->left;
48 prc->top = (prcBase->top + prcBase->bottom - GRIP_SIZE) / 2;
49 break;
50 case HIT_MIDDLE_RIGHT:
51 prc->left = prcBase->right - GRIP_SIZE;
52 prc->top = (prcBase->top + prcBase->bottom - GRIP_SIZE) / 2;
53 break;
54 case HIT_LOWER_LEFT:
55 prc->left = prcBase->left;
56 prc->top = prcBase->bottom - GRIP_SIZE;
57 break;
58 case HIT_LOWER_CENTER:
59 prc->left = (prcBase->left + prcBase->right - GRIP_SIZE) / 2;
60 prc->top = prcBase->bottom - GRIP_SIZE;
61 break;
62 case HIT_LOWER_RIGHT:
63 prc->left = prcBase->right - GRIP_SIZE;
64 prc->top = prcBase->bottom - GRIP_SIZE;
65 break;
66 case HIT_INNER:
67 *prc = *prcBase;
68 ::InflateRect(prc, -GRIP_SIZE, -GRIP_SIZE);
69 return TRUE;
70 default:
71 ::SetRectEmpty(prc);
72 return FALSE;
73 }
74
75 prc->right = prc->left + GRIP_SIZE;
76 prc->bottom = prc->top + GRIP_SIZE;
77 return TRUE;
78 }
79
getSizeBoxHitTest(POINT pt,LPCRECT prcBase)80 HITTEST getSizeBoxHitTest(POINT pt, LPCRECT prcBase)
81 {
82 CRect rc;
83
84 if (!::PtInRect(prcBase, pt))
85 return HIT_NONE;
86
87 rc = *prcBase;
88 rc.InflateRect(-GRIP_SIZE, -GRIP_SIZE);
89 if (rc.PtInRect(pt))
90 return HIT_INNER;
91
92 for (INT i = HIT_UPPER_LEFT; i <= HIT_LOWER_RIGHT; ++i)
93 {
94 HITTEST hit = (HITTEST)i;
95 getSizeBoxRect(&rc, hit, prcBase);
96 if (rc.PtInRect(pt))
97 return hit;
98 }
99
100 return HIT_BORDER;
101 }
102
drawSizeBoxes(HDC hdc,LPCRECT prcBase,BOOL bDrawFrame,LPCRECT prcPaint)103 VOID drawSizeBoxes(HDC hdc, LPCRECT prcBase, BOOL bDrawFrame, LPCRECT prcPaint)
104 {
105 CRect rc, rcIntersect;
106
107 if (prcPaint && !::IntersectRect(&rcIntersect, prcPaint, prcBase))
108 return;
109
110 if (bDrawFrame)
111 {
112 rc = *prcBase;
113 rc.InflateRect(-GRIP_SIZE / 2, -GRIP_SIZE / 2);
114
115 LOGBRUSH logBrush = { BS_HOLLOW, 0, 0 };
116 COLORREF rgbHighlight = ::GetSysColor(COLOR_HIGHLIGHT);
117 HGDIOBJ oldPen = ::SelectObject(hdc, ::CreatePen(PS_DOT, 1, rgbHighlight));
118 HGDIOBJ oldBrush = ::SelectObject(hdc, ::CreateBrushIndirect(&logBrush));
119 ::Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
120 ::DeleteObject(::SelectObject(hdc, oldBrush));
121 ::DeleteObject(::SelectObject(hdc, oldPen));
122 }
123
124 for (INT i = HIT_UPPER_LEFT; i <= HIT_LOWER_RIGHT; ++i)
125 {
126 getSizeBoxRect(&rc, (HITTEST)i, prcBase);
127 if (!prcPaint || ::IntersectRect(&rcIntersect, &rc, prcPaint))
128 ::FillRect(hdc, &rc, (HBRUSH)(COLOR_HIGHLIGHT + 1));
129 }
130 }
131