1 /////////////////////////////////////////////////////////////////////////////
3 // This file is part of ResizableLib
4 // http://sourceforge.net/projects/resizablelib
6 // Copyright (C) 2000-2004 by Paolo Messina
7 // http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com
9 // The contents of this file are subject to the Artistic License (the "License").
10 // You may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at:
12 // http://www.opensource.org/licenses/artistic-license.html
14 // If you find this code useful, credits would be nice!
16 /////////////////////////////////////////////////////////////////////////////
20 * @brief Implementation of the CResizableGrip class.
24 #include "ResizableGrip.h"
28 static char THIS_FILE
[]=__FILE__
;
32 //////////////////////////////////////////////////////////////////////
33 // Construction/Destruction
34 //////////////////////////////////////////////////////////////////////
36 CResizableGrip::CResizableGrip()
41 CResizableGrip::~CResizableGrip()
46 void CResizableGrip::UpdateSizeGrip()
48 if (!::IsWindow(m_wndGrip
.m_hWnd
))
51 // size-grip goes bottom right in the client area
52 // (any right-to-left adjustment should go here)
55 GetResizableWnd()->GetClientRect(&rect
);
57 rect
.left
= rect
.right
- m_wndGrip
.m_size
.cx
;
58 rect
.top
= rect
.bottom
- m_wndGrip
.m_size
.cy
;
60 // must stay below other children
61 m_wndGrip
.SetWindowPos(&CWnd::wndBottom
, rect
.left
, rect
.top
, 0, 0,
62 SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOREPOSITION
63 | (IsSizeGripVisible() ? SWP_SHOWWINDOW
: SWP_HIDEWINDOW
));
66 // pbStatus points to a variable, maintained by the caller, that
67 // holds its visibility status. Initialize the variable with 1
68 // to allow to temporarily hide the grip, 0 to allow to
69 // temporarily show the grip (with respect to the dwMask bit).
71 // NB: visibility is effective only after an update
73 void CResizableGrip::ShowSizeGrip(DWORD
* pStatus
, DWORD dwMask
/*= 1*/)
75 ASSERT(pStatus
!= NULL
);
77 if (!(*pStatus
& dwMask
))
84 void CResizableGrip::HideSizeGrip(DWORD
* pStatus
, DWORD dwMask
/*= 1*/)
86 ASSERT(pStatus
!= NULL
);
88 if (*pStatus
& dwMask
)
91 (*pStatus
) &= ~dwMask
;
95 BOOL
CResizableGrip::IsSizeGripVisible()
97 // NB: visibility is effective only after an update
98 return (m_nShowCount
> 0);
101 void CResizableGrip::SetSizeGripVisibility(BOOL bVisible
)
109 BOOL
CResizableGrip::SetSizeGripBkMode(int nBkMode
)
111 if (::IsWindow(m_wndGrip
.m_hWnd
))
113 if (nBkMode
== OPAQUE
)
114 m_wndGrip
.SetTransparency(FALSE
);
115 else if (nBkMode
== TRANSPARENT
)
116 m_wndGrip
.SetTransparency(TRUE
);
124 void CResizableGrip::SetSizeGripShape(BOOL bTriangular
)
126 if (::IsWindow(m_wndGrip
.m_hWnd
))
127 m_wndGrip
.SetTriangularShape(bTriangular
);
130 BOOL
CResizableGrip::CreateSizeGrip(BOOL bVisible
/*= TRUE*/,
131 BOOL bTriangular
/*= TRUE*/, BOOL bTransparent
/*= FALSE*/)
134 CRect
rect(0 , 0, m_wndGrip
.m_size
.cx
, m_wndGrip
.m_size
.cy
);
135 BOOL bRet
= m_wndGrip
.Create(WS_CHILD
| WS_CLIPSIBLINGS
136 | SBS_SIZEGRIP
, rect
, GetResizableWnd(), 0);
141 m_wndGrip
.SetTriangularShape(bTriangular
);
142 m_wndGrip
.SetTransparency(bTransparent
);
143 SetSizeGripVisibility(bVisible
);
152 /////////////////////////////////////////////////////////////////////////////
153 // CSizeGrip implementation
155 BOOL
CResizableGrip::CSizeGrip::IsRTL()
157 return GetExStyle() & WS_EX_LAYOUTRTL
;
160 BOOL
CResizableGrip::CSizeGrip::PreCreateWindow(CREATESTRUCT
& cs
)
163 m_size
.cx
= GetSystemMetrics(SM_CXVSCROLL
);
164 m_size
.cy
= GetSystemMetrics(SM_CYHSCROLL
);
169 return CScrollBar::PreCreateWindow(cs
);
172 LRESULT
CResizableGrip::CSizeGrip::WindowProc(UINT message
,
173 WPARAM wParam
, LPARAM lParam
)
178 // fix to prevent the control to gain focus, using arrow keys
179 // (standard grip returns DLGC_WANTARROWS, like any standard scrollbar)
183 // fix to prevent the control to gain focus, if set directly
184 // (for example when it's the only one control in a dialog)
188 // choose proper cursor shape
192 return HTBOTTOMRIGHT
;
195 case WM_SETTINGCHANGE
:
197 // update grip's size
198 CSize sizeOld
= m_size
;
199 m_size
.cx
= GetSystemMetrics(SM_CXVSCROLL
);
200 m_size
.cy
= GetSystemMetrics(SM_CYHSCROLL
);
202 // resize transparency bitmaps
208 m_bmGrip
.DeleteObject();
209 m_bmMask
.DeleteObject();
212 m_bmGrip
.CreateCompatibleBitmap(&dc
, m_size
.cx
, m_size
.cy
);
213 m_bmMask
.CreateBitmap(m_size
.cx
, m_size
.cy
, 1, 1, NULL
);
218 SetTriangularShape(m_bTriangular
);
220 // reposition the grip
223 rect
.InflateRect(m_size
.cx
- sizeOld
.cx
, m_size
.cy
- sizeOld
.cy
, 0, 0);
224 ::MapWindowPoints(NULL
, GetParent()->GetSafeHwnd(), (LPPOINT
)&rect
, 2);
225 MoveWindow(rect
, TRUE
);
232 SetTransparency(FALSE
);
240 CDC
* pDC
= (message
== WM_PAINT
&& wParam
== 0) ?
241 BeginPaint(&ps
) : CDC::FromHandle((HDC
)wParam
);
244 CBitmap
*pOldGrip
, *pOldMask
;
246 pOldGrip
= m_dcGrip
.SelectObject(&m_bmGrip
);
247 pOldMask
= m_dcMask
.SelectObject(&m_bmMask
);
249 // obtain original grip bitmap, make the mask and prepare masked bitmap
250 CScrollBar::WindowProc(message
, (WPARAM
)m_dcGrip
.GetSafeHdc(), lParam
);
251 m_dcGrip
.SetBkColor(m_dcGrip
.GetPixel(0, 0));
252 m_dcMask
.BitBlt(0, 0, m_size
.cx
, m_size
.cy
, &m_dcGrip
, 0, 0, SRCCOPY
);
253 m_dcGrip
.BitBlt(0, 0, m_size
.cx
, m_size
.cy
, &m_dcMask
, 0, 0, 0x00220326);
255 // draw transparently
256 pDC
->BitBlt(0, 0, m_size
.cx
, m_size
.cy
, &m_dcMask
, 0, 0, SRCAND
);
257 pDC
->BitBlt(0, 0, m_size
.cx
, m_size
.cy
, &m_dcGrip
, 0, 0, SRCPAINT
);
260 m_dcGrip
.SelectObject(pOldGrip
);
261 m_dcMask
.SelectObject(pOldMask
);
263 if (message
== WM_PAINT
&& wParam
== 0)
270 return CScrollBar::WindowProc(message
, wParam
, lParam
);
273 void CResizableGrip::CSizeGrip::SetTransparency(BOOL bActivate
)
275 // creates or deletes DCs and Bitmaps used for
276 // implementing a transparent size grip
278 if (bActivate
&& !m_bTransparent
)
280 m_bTransparent
= TRUE
;
284 // create memory DCs and bitmaps
285 m_dcGrip
.CreateCompatibleDC(&dc
);
286 m_bmGrip
.CreateCompatibleBitmap(&dc
, m_size
.cx
, m_size
.cy
);
288 m_dcMask
.CreateCompatibleDC(&dc
);
289 m_bmMask
.CreateBitmap(m_size
.cx
, m_size
.cy
, 1, 1, NULL
);
291 else if (!bActivate
&& m_bTransparent
)
293 m_bTransparent
= FALSE
;
295 // destroy memory DCs and bitmaps
297 m_bmGrip
.DeleteObject();
300 m_bmMask
.DeleteObject();
304 void CResizableGrip::CSizeGrip::SetTriangularShape(BOOL bEnable
)
306 m_bTriangular
= bEnable
;
310 // set a triangular window region
313 rect
.OffsetRect(-rect
.TopLeft());
316 { rect
.left
, rect
.bottom
},
317 { rect
.right
, rect
.bottom
},
318 { rect
.right
, rect
.top
}
321 rgnGrip
.CreatePolygonRgn(arrPoints
, 3, WINDING
);
322 SetWindowRgn((HRGN
)rgnGrip
.Detach(), IsWindowVisible());
326 SetWindowRgn((HRGN
)NULL
, IsWindowVisible());