ResizableGrip.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // ResizableGrip.cpp: implementation of the CResizableGrip class.
  2. //
  3. /////////////////////////////////////////////////////////////////////////////
  4. //
  5. // Copyright (C) 2000-2001 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
  12. //
  13. // If you find this code useful, credits would be nice!
  14. //
  15. /////////////////////////////////////////////////////////////////////////////
  16. #include "stdafx.h"
  17. #include "ResizableGrip.h"
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[]=__FILE__;
  21. #define new DEBUG_NEW
  22. #endif
  23. //////////////////////////////////////////////////////////////////////
  24. // Construction/Destruction
  25. //////////////////////////////////////////////////////////////////////
  26. CResizableGrip::CResizableGrip()
  27. {
  28. m_sizeGrip.cx = GetSystemMetrics(SM_CXVSCROLL);
  29. m_sizeGrip.cy = GetSystemMetrics(SM_CYHSCROLL);
  30. }
  31. CResizableGrip::~CResizableGrip()
  32. {
  33. }
  34. void CResizableGrip::UpdateGripPos()
  35. {
  36. // size-grip goes bottom right in the client area
  37. // (any right-to-left adjustment should go here)
  38. RECT rect;
  39. GetResizableWnd()->GetClientRect(&rect);
  40. rect.left = rect.right - m_sizeGrip.cx;
  41. rect.top = rect.bottom - m_sizeGrip.cy;
  42. // must stay below other children
  43. m_wndGrip.SetWindowPos(&CWnd::wndBottom, rect.left, rect.top, 0, 0,
  44. SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREPOSITION);
  45. // maximized windows cannot be resized
  46. if (GetResizableWnd()->IsZoomed())
  47. m_wndGrip.EnableWindow(FALSE);
  48. else
  49. m_wndGrip.EnableWindow(TRUE);
  50. }
  51. void CResizableGrip::ShowSizeGrip(BOOL bShow)
  52. {
  53. m_wndGrip.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  54. }
  55. #define RSZ_GRIP_OBJ _T("ResizableGrip")
  56. BOOL CResizableGrip::InitGrip()
  57. {
  58. CRect rect(0 , 0, m_sizeGrip.cx, m_sizeGrip.cy);
  59. BOOL bRet = m_wndGrip.Create(WS_CHILD | WS_CLIPSIBLINGS | SBS_SIZEGRIP,
  60. rect, GetResizableWnd(), 0);
  61. if (bRet)
  62. {
  63. // set a triangular window region
  64. CRgn rgnGrip, rgn;
  65. rgn.CreateRectRgn(0,0,1,1);
  66. rgnGrip.CreateRectRgnIndirect(&rect);
  67. for (int y=0; y<m_sizeGrip.cy; y++)
  68. {
  69. rgn.SetRectRgn(0, y, m_sizeGrip.cx-y, y+1);
  70. rgnGrip.CombineRgn(&rgnGrip, &rgn, RGN_DIFF);
  71. }
  72. m_wndGrip.SetWindowRgn((HRGN)rgnGrip.Detach(), FALSE);
  73. // subclass control
  74. ::SetProp(m_wndGrip, RSZ_GRIP_OBJ,
  75. (HANDLE)::GetWindowLong(m_wndGrip, GWL_WNDPROC));
  76. ::SetWindowLong(m_wndGrip, GWL_WNDPROC, (LONG)GripWindowProc);
  77. // update pos
  78. UpdateGripPos();
  79. ShowSizeGrip();
  80. }
  81. return bRet;
  82. }
  83. LRESULT CResizableGrip::GripWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  84. {
  85. WNDPROC oldWndProc = (WNDPROC)::GetProp(hwnd, RSZ_GRIP_OBJ);
  86. switch (msg)
  87. {
  88. case WM_NCHITTEST:
  89. // choose proper cursor shape
  90. if (IsRTL(hwnd))
  91. return HTBOTTOMLEFT;
  92. else
  93. return HTBOTTOMRIGHT;
  94. case WM_DESTROY:
  95. // unsubclass
  96. ::RemoveProp(hwnd, RSZ_GRIP_OBJ);
  97. ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)oldWndProc);
  98. break;
  99. }
  100. return ::CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam);
  101. }