Win32弹出窗口“晃动”调整大小时

发布于 2024-12-12 05:16:12 字数 2913 浏览 0 评论 0原文

我正在编写一个带有最顶层窗口的 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;
}

I'm writing a C++ program with a topmost window so you don't have any default way of resizing, or at least not to my knowledge. So I've implemented a resize, which is working fine except for 1 detail.

When I resize the window on the right or bottom it works perfectly, but when I'm resizing left or on the top, then the right, or bottom part, depending on which way you're resizing, shakes. I already "fixed" it partially so when you're downsizing it looks fine, but when you're upsizing the window it still shakes.

I also already tried to disable and enable the redraw when resizing but that screws things up completely,

Here's the code I'm currently using

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

And the methods which are called from the 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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无需解释 2024-12-19 05:16:12

汉斯是对的……你正在以艰难的方式解决这个问题。

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

Hans is right... you're going about this the hard way.

Write a message handler for WM_NCHITTEST (in MFC, override ::OnNcHitTest) that returns HT_BOTTOM, HT_LEFT, etc etc depending on where you want the "borders" of your window to be, and let Windows handle the whole thing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文