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 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 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 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 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