调整大小时c ++ win32弹出窗口“摇动”

时间:2011-10-28 17:49:16

标签: c++ winapi popup window resize

我正在编写一个带有最顶层窗口的c ++程序,因此您没有任何默认的调整大小,或者至少不是我的知识。所以我实现了一个resize,除了1个细节外,它工作得很好。 当我在右侧或底部调整窗口大小时,它可以完美地工作,但是当我调整左侧或顶部,然后右侧或底部,取决于您正在调整大小的方式,摇动。我已经“部分”修复了它,所以当你缩小尺寸时看起来很好,但是当你对窗户进行尺寸调整时,它仍然会震动。

我也已经尝试在调整大小时禁用并启用重绘但是完全搞砸了:p

这是我正在使用的代码

GetCursorPos(&m_MousePos);
  int x( m_rWindowStart.left ),
     y( m_rWindowStart.top ),
     w( m_pWindow->GetWidth() ),
     h( m_pWindow->GetHeight() );
  //sizing
  switch (m_SizingDir)
  {
  case SIZING_DIR_LEFT:
     //x += m_MousePos.x - m_MousePosOld.x;

     w = m_rWindowStart.right - m_MousePos.x - m_MousePosOld.x + x;
     w /= m_SnapSizing;
     w *= m_SnapSizing;

     x = m_rWindowStart.right - w;
     break;
  case SIZING_DIR_TOP:
     y += m_MousePos.y - m_MousePosOld.y;
     h = m_rWindowStart.bottom - y;
     break;
  case SIZING_DIR_RIGHT:
     w = m_rWindowStart.right - m_rWindowStart.left + m_MousePos.x - m_MousePosOld.x;
     break;
  case SIZING_DIR_BOTTOM:
     h = m_rWindowStart.bottom - m_rWindowStart.top + m_MousePos.y - m_MousePosOld.y;
     break;
  case SIZING_DIR_LEFTTOP:
     x += m_MousePos.x - m_MousePosOld.x;
     w = m_rWindowStart.right - x;
     y += m_MousePos.y - m_MousePosOld.y;
     h = m_rWindowStart.bottom - y;
     break;
  case SIZING_DIR_LEFTBOTTOM:
     x += m_MousePos.x - m_MousePosOld.x;
     w = m_rWindowStart.right - x;
     h = m_rWindowStart.bottom - m_rWindowStart.top + m_MousePos.y - m_MousePosOld.y;
     break;
  case SIZING_DIR_RIGHTTOP:
     w = m_rWindowStart.right - m_rWindowStart.left + m_MousePos.x - m_MousePosOld.x;
     y += m_MousePos.y - m_MousePosOld.y;
     h = m_rWindowStart.bottom - y;
     break;
  case SIZING_DIR_RIGHTBOTTOM:
     w = m_rWindowStart.right - m_rWindowStart.left + m_MousePos.x - m_MousePosOld.x;
     h = m_rWindowStart.bottom - m_rWindowStart.top + m_MousePos.y - m_MousePosOld.y;
     break;
  }

  //window size snaps
  w /= m_SnapSizing;
  w *= m_SnapSizing;
  h /= m_SnapSizing;
  h *= m_SnapSizing;

  //limit sizing
  if (h < 20)
     h = 20;
  if (w < 20)
     w = 20;

  //move window ( x, y, w, h, repaint)
  m_pWindow->SetPosAndSize(x, y, w, h, true);

以及从m_pWindow

调用的方法
void Window::SetPosAndSize(int x, int y, int w, int h, bool repaint)
{
  ASSERT( w >= 0, _T("w(Width) must be greater than 0") );
  ASSERT( h >= 0, _T("h(Height) must be greater than 0") );

  m_Width = w;
  m_Height = h;

  if( m_hWnd )
  {
     RECT rPos;

     GetRect( rPos );   
     AdjustFromClient(w, h);

     MoveWindow(m_hWnd, x, y, w, h, repaint);
  }
}
void Window::GetRect( RECT& r ) const
{
   ::GetWindowRect( m_hWnd, &r );
}
void Window::AdjustFromClient(int& w, int& h) const
{
   RECT rSize2be = { 0, 0, w, h };
   AdjustWindowRect(&rSize2be, m_Style, false);

   w = rSize2be.right-rSize2be.left;
   h = rSize2be.bottom-rSize2be.top;
}

这里有一个例子,说明对于那些不完全理解问题的人来说 http://www.megaupload.com/?d=4AXXPFKI

按ctrl并单击以移动窗口和 按alt键并在边框附近单击以调整大小

1 个答案:

答案 0 :(得分:2)

汉斯是对的......你正在努力解决这个问题。

WM_NCHITTEST编写一个消息处理程序(在MFC中,覆盖::OnNcHitTest),返回HT_BOTTOM,HT_LEFT等,具体取决于你想要窗口的“边框”的位置,并让Windows处理整件事。