⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resizectrl.cpp

📁 界面编程的一些实现方法打包,VC中实现,比较新颖,大家
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if( m_array->GetAt( current ).handle == hWndCtl )
    {
      m_array->RemoveAt( current );
      return TRUE;
    }
  }
  return FALSE;
}

BOOL CResizeCtrl::GetWindowRect( RECT * rect )
{
  if( rect )
  {
    *rect = m_windowRect;
    return TRUE;
  }
  else
    return FALSE;
}
BOOL CResizeCtrl::CalcValue(int delta, int part, int & pending, long &position, BOOL isSize)
{
  if( part > 0 )
  {
    int toAdd = ( delta * part ) + pending;
    if( toAdd != 0 )
    {
      position  += ( toAdd / m_maxPart );
      pending    =   toAdd % m_maxPart ;
      // avoid negative width or height
      if( TRUE == isSize && position < 0 )
      {
        pending += ( position * m_maxPart );
        position = 0;
      }
      return TRUE;
    }
  }
  return FALSE;
}

void CResizeCtrl::Resize(int cx, int cy)
{
  ASSERT ( m_array );

  if( FALSE == m_inResize )
  {
    m_inResize     = TRUE;
    int upperBound = m_array->GetUpperBound();
    if( upperBound >= 0 )
    {
      int deltaX = cx - m_size.cx;
      int deltaY = cy - m_size.cy;

      if( deltaX != 0 || deltaY != 0 )
      {
        CRPItemState * items = m_array->GetData();
        HDWP  hdwp = ::BeginDeferWindowPos( 0 );
        for( int current = 0; current <= upperBound; current++, items++ )
        {
          RECT rcItem;
        
          
          ::GetWindowRect( items->handle, & rcItem );
          ::MapWindowPoints( HWND_DESKTOP, m_hWndParent, (LPPOINT)(RECT*)&rcItem, 2 );
          rcItem.right  -= rcItem.left;
          rcItem.bottom -= rcItem.top;

          BOOL changed = FALSE;
          
          changed |= CalcValue( deltaX, items->part.left,   items->pending.left,   rcItem.left,   FALSE );
          changed |= CalcValue( deltaX, items->part.width,  items->pending.width,  rcItem.right,  TRUE );
          changed |= CalcValue( deltaY, items->part.top,    items->pending.top,    rcItem.top,    FALSE );
          changed |= CalcValue( deltaY, items->part.height, items->pending.height, rcItem.bottom, TRUE );

          if( changed )
          {
            hdwp = ::DeferWindowPos( hdwp, items->handle, NULL,
                                     rcItem.left, rcItem.top,
                                     rcItem.right, rcItem.bottom, SWP_NOZORDER	);
          }

        }
        ::EndDeferWindowPos( hdwp );
        m_size.cx = cx;
        m_size.cy = cy;
      }
    }
    m_inResize = FALSE;
  }
}


LRESULT CALLBACK CResizeCtrl::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  LRESULT result = 0;
  CResizeCtrl * This = reinterpret_cast<CResizeCtrl *>(::GetProp( hWnd, m_szResizeProperty ));
  if( This )
  {
    WNDPROC prevWndProc = This->m_prevWndProc;
    if( FALSE == This->ProcessMessage( msg, wParam, lParam, result ) )
      result =  ::CallWindowProc( prevWndProc, hWnd, msg, wParam, lParam );
  }
  return result;
}



void CResizeCtrl::ChangeStyle(BOOL enable)
{
  ASSERT( m_hWndParent );
  ASSERT( m_hasResizingBorder == FALSE );
  CRect rect;
  
  BOOL hasMenu = ::GetMenu( m_hWndParent ) != NULL;
  long style   = ::GetWindowLong( m_hWndParent, GWL_STYLE );
  ::GetWindowRect( m_hWndParent, &rect );
  
  // retrieve client Rectangle
  RECT oldClientRect;
  ::GetClientRect( m_hWndParent, &oldClientRect );
  RECT newClientRect = oldClientRect;
  
  // adjust rect with current style
  ::AdjustWindowRect( &oldClientRect, style, hasMenu );

  if( enable )
  {
    style |= WS_THICKFRAME;
  }
  else
  {
    style &= ~WS_THICKFRAME;
  }
  
  // adjust rect with new style
  ::AdjustWindowRect( &newClientRect, style, hasMenu );

  // and adjust the windowrect, so that the clientrect remains equal
  rect.left   += ( newClientRect.left   - oldClientRect.left );
  rect.right  += ( newClientRect.right  - oldClientRect.right );
  rect.top    += ( newClientRect.top    - oldClientRect.top   );
  rect.bottom += ( newClientRect.bottom - oldClientRect.bottom );
  
  ::SetWindowLong( m_hWndParent, GWL_STYLE, style );
  ::SetWindowPos ( m_hWndParent, HWND_DESKTOP, rect.left, rect.top, rect.Width(), rect.Height(),
                   SWP_NOZORDER | SWP_NOACTIVATE  );

}

BOOL CResizeCtrl::ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam, LRESULT & result)
{
  BOOL handled = FALSE;
  if( m_gripEnabled && WM_NCHITTEST == message )
  {
    POINT pt = { (int)LOWORD(lParam), (int)HIWORD(lParam) };
    ::ScreenToClient( m_hWndParent, &pt);
    if( ::PtInRect ( m_gripRect, pt ) )
    {
      result  = HTBOTTOMRIGHT;
      handled = TRUE;
    }
  }
  else if( m_gripEnabled && WM_PAINT == message )
  {
    // First let the previous windowproc handle the WM_SIZE message
    result = ::CallWindowProc( m_prevWndProc, m_hWndParent, message, wParam, lParam );
    HDC hDC = ::GetDC( m_hWndParent );
    DrawFrameControl(hDC, &m_gripRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
    ::ReleaseDC( m_hWndParent, hDC ); 
    // flag message handled
    handled = TRUE;
  }
  else if( WM_DESTROY == message )
  {
    // Remove subclassing
    SetEnabled( FALSE );
  }
  else if( WM_SIZE == message )
  {
    // First let the previous windowproc handle the WM_SIZE message
    result = ::CallWindowProc( m_prevWndProc, m_hWndParent, message, wParam, lParam );
    // resize all registered controls
    Resize( (int)LOWORD(lParam) , (int)HIWORD(lParam) );
    if( m_gripEnabled )
    {
      ::InvalidateRect( m_hWndParent, m_gripRect, TRUE );
      GetGripRect( m_gripRect, TRUE );
    }
    // flag message handled
    handled = TRUE;
  }
  else if( WM_GETMINMAXINFO == message )
  {
    // First let the previous windowproc handle the WM_GETMINMAXINFO message
    result = ::CallWindowProc( m_prevWndProc, m_hWndParent, message, wParam, lParam );
    MINMAXINFO * lpMMI = (MINMAXINFO * )lParam;
    if( m_minTracking.cx == -1 )
      m_minTracking.cx = lpMMI->ptMinTrackSize.x;

    if( m_minTracking.cy == -1 )
      m_minTracking.cy = lpMMI->ptMinTrackSize.y;

    if( m_maxTracking.cx == -1 )
      m_maxTracking.cx = lpMMI->ptMaxTrackSize.x;
    
    if( m_maxTracking.cy == -1 )
      m_maxTracking.cy = lpMMI->ptMaxTrackSize.y;

    lpMMI->ptMinTrackSize.x = m_minTracking.cx;
    lpMMI->ptMinTrackSize.y = m_minTracking.cy;
    lpMMI->ptMaxTrackSize.x = m_maxTracking.cx;
    lpMMI->ptMaxTrackSize.y = m_maxTracking.cy;
    // flag message handled
    handled = TRUE;
  }
  else
  {
    // if the original window had no resizing border
    // we must serve WM_MOUSE, WM_NCLBUTTONDOWN and
    // WM_LBUTTONUP to enable resizing
    if( !m_hasResizingBorder )
    {
    	POINT mousePostion;
   	  RECT  currentRect;

      if( WM_MOUSEMOVE == message )
      {
		    if (m_hitCode && !m_inMouseMove )
		    {
			    m_inMouseMove = TRUE;
			    
          ::GetCursorPos( &mousePostion );
			    mousePostion.x += m_delta.cx;
			    mousePostion.y += m_delta.cy;
			    
          RECT  m_previsionRect;

          ::GetWindowRect( m_hWndParent, &currentRect );
			    m_previsionRect = currentRect;

			    switch( m_hitCode )
			    {
			      case HTTOPLEFT     : currentRect.left   = mousePostion.x; // fall through
			      case HTTOP         : currentRect.top    = mousePostion.y;	break;

			      case HTBOTTOMRIGHT : currentRect.right  = mousePostion.x; // fall through
			      case HTBOTTOM      : currentRect.bottom = mousePostion.y; break;

			      case HTBOTTOMLEFT  : currentRect.bottom = mousePostion.y; // fall through
			      case HTLEFT        : currentRect.left   = mousePostion.x;	break;

			      case HTTOPRIGHT    : currentRect.top    = mousePostion.y; // fall through
			      case HTRIGHT       : currentRect.right  = mousePostion.x;	break;
			    }
			    if (!::EqualRect( &currentRect, &m_previsionRect ))
          {
            int width  = currentRect.right - currentRect.left;
            int height = currentRect.bottom - currentRect.top;
						                
				    ::SetWindowPos( m_hWndParent, HWND_DESKTOP, currentRect.left, currentRect.top,	
                            width, height, SWP_NOZORDER | SWP_NOACTIVATE );
          }
			    m_inMouseMove = FALSE;
		    }
      }
      else if( WM_NCLBUTTONDOWN == message )
      {
        ::GetCursorPos( &mousePostion );
		    ::GetWindowRect( m_hWndParent, &currentRect );

		    m_hitCode  = wParam;
		    m_delta.cx = 
        m_delta.cy = 0;

		    switch( m_hitCode )
		    {
		      case HTTOPLEFT     : m_delta.cx = currentRect.left   - mousePostion.x; // fall through
		      case HTTOP         : m_delta.cy = currentRect.top    - mousePostion.y; break;

		      case HTBOTTOMRIGHT : m_delta.cx = currentRect.right  - mousePostion.x; // fall through
		      case HTBOTTOM      : m_delta.cy = currentRect.bottom - mousePostion.y; break;

          case HTBOTTOMLEFT  : m_delta.cy = currentRect.bottom - mousePostion.y; // fall through
		      case HTLEFT        : m_delta.cx = currentRect.left   - mousePostion.x; break;

          case HTTOPRIGHT    : m_delta.cy = currentRect.top    - mousePostion.y; // fall through
		      case HTRIGHT       : m_delta.cx = currentRect.right  - mousePostion.x; break;

          default            : m_hitCode = 0; break;
		    }

		    if (m_hitCode)
		    {
			    ::SetCapture( m_hWndParent );
		    }

      }
      else if( WM_LBUTTONUP == message )
      {
  		  if (m_hitCode != 0)
        {
		  	  ::ReleaseCapture();
			    m_hitCode   = 0;
        }
      }
    }
  }
  return handled;
}
///////////////////////////////////////////////////////////////////////
// MinMaxInfo Support

BOOL  CResizeCtrl::SetMinimumTrackingSize( const CSize & size )
{
  m_minTracking = size;
  return TRUE;
}
BOOL  CResizeCtrl::SetMinimumTrackingSize()
{
  RECT  rect;
  ::GetWindowRect( m_hWndParent, &rect );
  return SetMinimumTrackingSize( CSize( rect.right - rect.left, rect.bottom - rect.top ) );
}
CSize CResizeCtrl::GetMinimumTrackingSize( )
{
  return m_minTracking;
}

BOOL  CResizeCtrl::SetMaximumTrackingSize( const CSize & size )
{
  m_maxTracking = size;
  return TRUE;
}
CSize CResizeCtrl::GetMaximumTrackingSize( )
{
  return m_maxTracking;
}


void CResizeCtrl::GetGripRect(RECT & rect, BOOL redraw)
{
  GetClientRect( m_hWndParent, &rect );
  rect.left = rect.right  - ::GetSystemMetrics(SM_CXVSCROLL) ;
  rect.top  = rect.bottom - ::GetSystemMetrics(SM_CYHSCROLL) ;
  if( redraw )
    ::InvalidateRect( m_hWndParent, &rect, TRUE );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -