【问题标题】:MFC Controls are getting disappeared after scrolling滚动后 MFC 控件消失
【发布时间】:2011-04-14 15:14:14
【问题描述】:

我正在开发 WinCE 中基于对话框的 MFC 应用程序。 我在对话框中创建了几个控件并向下滚动。 当我再次向上滚动时,第一个屏幕中的控件消失了。

在 OnInitDialog() 中创建的控件如下图坐标 (50,10)

test->Create(_T("Title"), WS_CHILD|WS_VISIBLE, CRect(50,10,200,40), this, ID_TITLE);

我在 OnVScroll() 中进行的滚动处理,如下所示

 switch(nSBCode)
 {
  case SB_LINEDOWN:
  {
   if(nPos < max)
   {
    ScrollWindowEx(0, SCROLLDOWN_LINE_STEPSIZE, CRect(0,0, rect.right - 25, rect.bottom), NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE); 
    pScrollBar->SetScrollPos(nPos - SCROLLDOWN_LINE_STEPSIZE); //nPos+10
   }
   break;
  }
  case SB_LINEUP:
  {
   if(nPos > min)
   {
    ScrollWindowEx(0, SCROLLUP_LINE_STEPSIZE, CRect(0,0, rect.right - 25, rect.bottom), NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE); 
    pScrollBar->SetScrollPos(nPos - SCROLLUP_LINE_STEPSIZE); //Ex: nPos-10
   }
   break;
  }

 default:
  printf("Notimplemented");
  break;
 }

我正在处理向下滚动和向上滚动。 向下滚动时,会显示 Dialog 中的所有控件。 但是在向上滚动时,顶部的控件消失了。

发生了什么事? 我应该在每次滚动时实现 OnPaint() 方法来绘制控件吗? 如果有,怎么做?

【问题讨论】:

  • 您是否正在对这些控件进行任何移动/调整大小?也许您在某处错误地计算了界限?它们仍然起作用还是完全消失了?如果您向下滚动一点,它们会部分消失,还是始终是整个控件?
  • 我的 WinCE 模拟器中没有最小化按钮。我正在使用带有 Visual Studio 2008 的 Windows Mobile 6.x SDK
  • @tenfour:总是整个控制消失。

标签: c++ visual-c++ mfc windows-mobile windows-ce


【解决方案1】:

我有以下代码可以正常工作。希望对你有帮助。

LRESULT CMyWindow::OnVScroll( UINT code, UINT position )
{
    SCROLLINFO info = { sizeof( SCROLLINFO ), SIF_ALL };
    GetScrollInfo( m_wnd, SB_VERT, &info );
    int previous_pos = info.nPos;
    switch( code )
    {
    case SB_TOP:
        info.nPos = 0;
        break;
    case SB_BOTTOM:
        info.nPos = info.nMax - info.nPage;
        break;
    case SB_LINEDOWN:
        info.nPos = min( info.nPos + 1, info.nMax - (int)info.nPage );
        break;
    case SB_LINEUP:
        info.nPos = max( info.nPos - 1, info.nMin );
        break;
    case SB_PAGEDOWN:
        info.nPos = min( info.nPos + (int)info.nPage, info.nMax - (int)info.nPage );
        break;
    case SB_PAGEUP:
        info.nPos = max( info.nPos - (int)info.nPage, info.nMin );
        break;
    case SB_THUMBTRACK:
    case SB_THUMBPOSITION:
        info.nPos = position;
        break;
    }
    int offset = previous_pos - info.nPos;
    if( offset != 0 )
    {
        ScrollWindowEx( m_wnd, 0, offset, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE );
        SetScrollPos( m_wnd, SB_VERT, info.nPos, FALSE );
    }
    return 0L;
}

【讨论】:

  • @bjskishore123 我很高兴它有帮助:)
  • 这不是解决方案。它将暴露您打算解决的相同问题:子窗口将消失。这在CWnd::ScrollWindowEx 的文档中有详细说明:“如果指定了 SW_SCROLLCHILDREN 标志,如果滚动子窗口的一部分,Windows 将无法正确更新屏幕。” 解决方案是手动移动子窗口调用DeferWindowPos
  • @IInspectable 这只会在子窗口的部分滚动时发生。由于我将NULL 传递给lpRectScroll 参数,因此整个孩子将滚动。
  • 我在您的回答中看不到任何可以确保子窗口不会部分移出客户区域,因此稍后部分移入的内容。子窗口可以位于客户区之外。结果是,它们变得(部分)不可见。您的代码无法防范这种情况。
【解决方案2】:

来自 ScrollWindowEx 文档:

dy
指定数量,单位为 设备单位,垂直滚动。 此参数必须为负数 值向上滚动。

我将相关短语加粗。

【讨论】:

  • 是的,我只在向下滚动时使用负值。抱歉,我没有在代码中显示宏值。
猜你喜欢
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-03-11
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
相关资源
最近更新 更多