Update UNRAR.H
[xy_vsfilter.git] / src / ui / ResizableLib / ResizableGrip.cpp
blobf1464dbb7f6db8b69c2f1290811e31559f28b765
1 // ResizableGrip.cpp: implementation of the CResizableGrip class.
2 //
3 /////////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2000-2002 by Paolo Messina
6 // (http://www.geocities.com/ppescher - ppescher@yahoo.com)
7 //
8 // The contents of this file are subject to the Artistic License (the "License").
9 // You may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at:
11 // http://www.opensource.org/licenses/artistic-license.html
13 // If you find this code useful, credits would be nice!
15 /////////////////////////////////////////////////////////////////////////////
17 #include "stdafx.h"
18 #include "ResizableGrip.h"
20 #ifdef _DEBUG
21 #undef THIS_FILE
22 static char THIS_FILE[]=__FILE__;
23 #define new DEBUG_NEW
24 #endif
26 //////////////////////////////////////////////////////////////////////
27 // Construction/Destruction
28 //////////////////////////////////////////////////////////////////////
30 CResizableGrip::CResizableGrip()
32 m_nShowCount = 0;
35 CResizableGrip::~CResizableGrip()
40 void CResizableGrip::UpdateSizeGrip()
42 ASSERT(::IsWindow(m_wndGrip.m_hWnd));
44 // size-grip goes bottom right in the client area
45 // (any right-to-left adjustment should go here)
47 RECT rect;
48 GetResizableWnd()->GetClientRect(&rect);
50 rect.left = rect.right - m_wndGrip.m_size.cx;
51 rect.top = rect.bottom - m_wndGrip.m_size.cy;
53 // must stay below other children
54 m_wndGrip.SetWindowPos(&CWnd::wndBottom, rect.left, rect.top, 0, 0,
55 SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREPOSITION
56 | (IsSizeGripVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
59 // pbStatus points to a variable, maintained by the caller, that
60 // holds its visibility status. Initialize the variable with 1
61 // to allow to temporarily hide the grip, 0 to allow to
62 // temporarily show the grip (with respect to the dwMask bit).
64 // NB: visibility is effective only after an update
66 void CResizableGrip::ShowSizeGrip(DWORD* pStatus, DWORD dwMask /*= 1*/)
68 ASSERT(pStatus != NULL);
70 if (!(*pStatus & dwMask))
72 m_nShowCount++;
73 (*pStatus) |= dwMask;
77 void CResizableGrip::HideSizeGrip(DWORD* pStatus, DWORD dwMask /*= 1*/)
79 ASSERT(pStatus != NULL);
81 if (*pStatus & dwMask)
83 m_nShowCount--;
84 (*pStatus) &= ~dwMask;
88 BOOL CResizableGrip::IsSizeGripVisible()
90 // NB: visibility is effective only after an update
91 return (m_nShowCount > 0);
94 void CResizableGrip::SetSizeGripVisibility(BOOL bVisible)
96 if (bVisible)
97 m_nShowCount = 1;
98 else
99 m_nShowCount = 0;
102 BOOL CResizableGrip::SetSizeGripBkMode(int nBkMode)
104 if (::IsWindow(m_wndGrip.m_hWnd))
106 if (nBkMode == OPAQUE)
107 m_wndGrip.SetTransparency(FALSE);
108 else if (nBkMode == TRANSPARENT)
109 m_wndGrip.SetTransparency(TRUE);
110 else
111 return FALSE;
112 return TRUE;
114 return FALSE;
117 void CResizableGrip::SetSizeGripShape(BOOL bTriangular)
119 m_wndGrip.SetTriangularShape(bTriangular);
122 BOOL CResizableGrip::CreateSizeGrip(BOOL bVisible /*= TRUE*/,
123 BOOL bTriangular /*= TRUE*/, BOOL bTransparent /*= FALSE*/)
125 // create grip
126 CRect rect(0 , 0, m_wndGrip.m_size.cx, m_wndGrip.m_size.cy);
127 BOOL bRet = m_wndGrip.Create(WS_CHILD | WS_CLIPSIBLINGS
128 | SBS_SIZEGRIP, rect, GetResizableWnd(), 0);
130 if (bRet)
132 // set options
133 m_wndGrip.SetTriangularShape(bTriangular);
134 m_wndGrip.SetTransparency(bTransparent);
135 SetSizeGripVisibility(bVisible);
137 // update position
138 UpdateSizeGrip();
141 return bRet;
144 /////////////////////////////////////////////////////////////////////////////
145 // CSizeGrip implementation
147 BOOL CResizableGrip::CSizeGrip::IsRTL()
149 return GetExStyle() & 0x00400000L/*WS_EX_LAYOUTRTL*/;
152 BOOL CResizableGrip::CSizeGrip::PreCreateWindow(CREATESTRUCT& cs)
154 // set window size
155 m_size.cx = GetSystemMetrics(SM_CXVSCROLL);
156 m_size.cy = GetSystemMetrics(SM_CYHSCROLL);
158 cs.cx = m_size.cx;
159 cs.cy = m_size.cy;
161 return CScrollBar::PreCreateWindow(cs);
164 LRESULT CResizableGrip::CSizeGrip::WindowProc(UINT message,
165 WPARAM wParam, LPARAM lParam)
167 switch (message)
169 case WM_GETDLGCODE:
170 // fix to prevent the control to gain focus, using arrow keys
171 // (standard grip returns DLGC_WANTARROWS, like any standard scrollbar)
172 return DLGC_STATIC;
174 case WM_NCHITTEST:
175 // choose proper cursor shape
176 if (IsRTL())
177 return HTBOTTOMLEFT;
178 else
179 return HTBOTTOMRIGHT;
180 break;
182 case WM_SETTINGCHANGE:
184 // update grip's size
185 CSize sizeOld = m_size;
186 m_size.cx = GetSystemMetrics(SM_CXVSCROLL);
187 m_size.cy = GetSystemMetrics(SM_CYHSCROLL);
189 // resize transparency bitmaps
190 if (m_bTransparent)
192 CClientDC dc(this);
194 // destroy bitmaps
195 m_bmGrip.DeleteObject();
196 m_bmMask.DeleteObject();
198 // re-create bitmaps
199 m_bmGrip.CreateCompatibleBitmap(&dc, m_size.cx, m_size.cy);
200 m_bmMask.CreateBitmap(m_size.cx, m_size.cy, 1, 1, NULL);
203 // re-calc shape
204 if (m_bTriangular)
205 SetTriangularShape(m_bTriangular);
207 // reposition the grip
208 CRect rect;
209 GetWindowRect(rect);
210 rect.InflateRect(m_size.cx - sizeOld.cx, m_size.cy - sizeOld.cy, 0, 0);
211 ::MapWindowPoints(NULL, GetParent()->GetSafeHwnd(), (LPPOINT)&rect, 2);
212 MoveWindow(rect, TRUE);
214 break;
216 case WM_DESTROY:
217 // perform clean up
218 if (m_bTransparent)
219 SetTransparency(FALSE);
220 break;
222 case WM_PAINT:
223 if (m_bTransparent)
225 CPaintDC dc(this);
227 // select bitmaps
228 CBitmap *pOldGrip, *pOldMask;
230 pOldGrip = m_dcGrip.SelectObject(&m_bmGrip);
231 pOldMask = m_dcMask.SelectObject(&m_bmMask);
233 // obtain original grip bitmap, make the mask and prepare masked bitmap
234 CScrollBar::WindowProc(WM_PAINT, (WPARAM)m_dcGrip.GetSafeHdc(), lParam);
235 m_dcGrip.SetBkColor(m_dcGrip.GetPixel(0, 0));
236 m_dcMask.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcGrip, 0, 0, SRCCOPY);
237 m_dcGrip.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcMask, 0, 0, 0x00220326);
239 // draw transparently
240 dc.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcMask, 0, 0, SRCAND);
241 dc.BitBlt(0, 0, m_size.cx, m_size.cy, &m_dcGrip, 0, 0, SRCPAINT);
243 // unselect bitmaps
244 m_dcGrip.SelectObject(pOldGrip);
245 m_dcMask.SelectObject(pOldMask);
247 return 0;
249 break;
252 return CScrollBar::WindowProc(message, wParam, lParam);
255 void CResizableGrip::CSizeGrip::SetTransparency(BOOL bActivate)
257 // creates or deletes DCs and Bitmaps used for
258 // implementing a transparent size grip
260 if (bActivate && !m_bTransparent)
262 m_bTransparent = TRUE;
264 CClientDC dc(this);
266 // create memory DCs and bitmaps
267 m_dcGrip.CreateCompatibleDC(&dc);
268 m_bmGrip.CreateCompatibleBitmap(&dc, m_size.cx, m_size.cy);
270 m_dcMask.CreateCompatibleDC(&dc);
271 m_bmMask.CreateBitmap(m_size.cx, m_size.cy, 1, 1, NULL);
273 else if (!bActivate && m_bTransparent)
275 m_bTransparent = FALSE;
277 // destroy memory DCs and bitmaps
278 m_dcGrip.DeleteDC();
279 m_bmGrip.DeleteObject();
281 m_dcMask.DeleteDC();
282 m_bmMask.DeleteObject();
286 void CResizableGrip::CSizeGrip::SetTriangularShape(BOOL bEnable)
288 m_bTriangular = bEnable;
290 if (bEnable)
292 // set a triangular window region
293 CRect rect;
294 GetWindowRect(rect);
295 rect.OffsetRect(-rect.TopLeft());
296 POINT arrPoints[] =
298 { rect.left, rect.bottom },
299 { rect.right, rect.bottom },
300 { rect.right, rect.top }
302 CRgn rgnGrip;
303 rgnGrip.CreatePolygonRgn(arrPoints, 3, WINDING);
304 SetWindowRgn((HRGN)rgnGrip.Detach(), IsWindowVisible());
306 else
308 SetWindowRgn((HRGN)NULL, IsWindowVisible());