【问题标题】:Win32 popup window "shaking" on resizeWin32 弹出窗口在调整大小时“摇晃”
【发布时间】:2023-03-09 13:22:02
【问题描述】:

我正在编写一个带有最顶层窗口的 C++ 程序,因此您没有任何默认的调整大小的方式,或者至少据我所知没有。所以我已经实现了调整大小,除了 1 个细节外,它工作正常。

当我在右侧或底部调整窗口大小时,它可以正常工作,但是当我在左侧或顶部调整大小时,右侧或底部部分会抖动,具体取决于您调整大小的方式。我已经部分“修复”了它,所以当你缩小它的大小时它看起来很好,但是当你放大窗口时它仍然会抖动。

我也已经尝试在调整大小时禁用和启用重绘,但这完全搞砸了,

这是我目前使用的代码

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;
}

【问题讨论】:

  • 因为当您从底部/右侧调整大小时,缓冲区不会重新绘制,当您调整顶部/左侧大小时,它会重新绘制。了解如何在您的 GUI 框架中进行双缓冲。
  • 我没有仔细看,通常的问题是当您移动窗口的左侧或顶部时,相对鼠标位置会发生变化。只是不要这样做,而是为 WM_NCHITTEST 编写一个消息处理程序。
  • (请针对您的新问题发布一个新问题。Stack Overflow 最适合处理一个问题,然后是多个答案——这不是论坛)

标签: c++ winapi popup window resize


【解决方案1】:

Hans 是对的……你正在努力解决这个问题。

为WM_NCHITTEST(在 MFC 中,覆盖::OnNcHitTest)编写一个消息处理程序,根据您希望窗口“边框”的位置返回 HT_BOTTOM、HT_LEFT 等,并让 Windows 处理整个事情.

【讨论】:

  • 我通过不使用WS_SYSMENU 样式使它像那样工作,但是当用户调整窗口内容可见时,这并不能解决问题,这里是它的发布版本megaupload.com/?d=JNAAVFWG
猜你喜欢
  • 2019-10-22
  • 2012-05-20
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多