【发布时间】: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