【问题标题】:Scroll bar moves with client in MFC滚动条在 MFC 中随客户端移动
【发布时间】:2019-11-25 11:37:22
【问题描述】:

我对 MFC 还很陌生。我实现了一个滚动条来滚动客户区。当我向下滚动时,滚动条也会随着客户端移动。我希望滚动条保持原位并移动客户端。

我尝试剪切滚动条并仅移动客户端,但无法使其正常工作。我使用 ScrollWindow() 来执行此操作,但我不知道如何剪辑滚动条。我不知道我是否需要滚动条的坐标/尺寸或什么来剪辑它,所以现在我将这些参数设置为 NULL。我专注于首先使用向上和向下按钮来让客户端正确移动。

int UpPos;
    if ((pScrollBar == (CScrollBar *)&mMotorScrollBar)) {

        // Determine the new position of scroll box.
        int CurPos = mMotorScrollBar.GetScrollPos();

        switch (nSBCode)
        {
        case SB_TOP:      // Scroll to top.
            CurPos = 0;
            break;

        case SB_BOTTOM:    // Scroll to bottom.
            CurPos = 122;
            break;

        case SB_ENDSCROLL: // End scroll.
            break;

        case SB_LINEUP: // Scroll up when arrow up button is clicked.
            if (CurPos > 0)
                CurPos--;
                UpPos = -CurPos;
                ScrollWindow(0, UpPos, NULL, NULL);
            break;

        case SB_LINEDOWN:   // Scroll down when arrow down button is clicked.
            if (CurPos < 122)
                CurPos++;
                ScrollWindow(0, CurPos, NULL, NULL);
            break;

Application before I scroll

Application after I scroll.

Window Properties

如您所见,滚动条也随着客户端移动。

【问题讨论】:

  • 可能是因为缺少对事件 WM_VSCROLL 的处理。这个link会提供一些线索。
  • 我在消息映射中添加了它并没有丢失,否则我的垂直滚动条根本无法工作。它的工作原理只是让客户端与滚动条一起滚动。
  • 您是如何创建 scollbar 的?您是否将滚动条控件拖放到对话框编辑器中?在这种情况下,上面的代码将移动带有滚动条的整个窗口。相反,您想让窗口具有垂直/水平滚动条属性。或者如果不是对话框,请使用CView。显示有关您的窗口以及滚动条的创建方式以及您希望它做什么的更多信息...
  • 我通过将滚动条从工具箱拖入对话框编辑器来创建滚动条。我在窗口属性中看到了垂直滚动条选项,但我不知道在哪里添加功能。因此,我制作了 CScrollBar。像所有其他按钮和滑块一样,给它一个 ID 等。
  • 也许考虑一个完全不同的实现?例如,带有内置标准滚动条的窗口?查看 WS_HSCROLLWS_VSCROLL 窗口样式的 Windows 文档。这些滚动条是自动显示的,与放置在对话框客户区的滚动条控件不同。如果需要,MFC 的 CScrollViewCFormView 类会自行显示滚动条,您只需定义可滚动区域的大小,其他所有内容都已包含在 MFC 库实现中。

标签: c++ user-interface mfc scrollbar


【解决方案1】:

使用SetScrollInfo 移除滚动条控件并添加垂直滚动条。 SetScrollInfo 必须在创建窗口时调用,它会添加一个滚动条并调整客户区。

此外,您可以编辑对话框并设置垂直滚动选项。除了调整对话框编辑器中对话框控件的位置外,此选项实际上没有任何作用。实际的滚动条必须在运行时使用SetScrollInfo 创建。示例:

BOOL CMyPropertyPage::OnInitDialog()
{
    BOOL res = CPropertyPage::OnInitDialog();
    SCROLLINFO si = { sizeof(si) };
    si.fMask = SIF_ALL;
    si.nMax = 122; //<- this should be calculated dynamically for DPI compatibility
    si.nPage = 1;
    SetScrollInfo(SB_VERT, &si, TRUE);
    return res;
}

void CMyPropertyPage::OnVScroll(UINT sbCode, UINT, CScrollBar*)
{
    SCROLLINFO si = { sizeof(si) };
    GetScrollInfo(SB_VERT, &si, SIF_ALL);
    int save = si.nPos;
    switch(sbCode)
    {
    case SB_LINEDOWN:      si.nPos += 1; break;
    case SB_LINEUP:        si.nPos -= 1; break;
    case SB_PAGEDOWN:      si.nPos += si.nPage; break;
    case SB_PAGEUP:        si.nPos -= si.nPage; break;
    case SB_TOP:           si.nPos = 0; break;
    case SB_BOTTOM:        si.nPos = si.nMax; break;
    case SB_THUMBTRACK:    si.nPos = si.nTrackPos; break;
    default:break;
    }
    if(si.nPos < 0) si.nPos = 0;
    if(si.nPos > si.nMax) si.nPos = si.nMax;
    SetScrollPos(SB_VERT, si.nPos); //update scrollbar position
    ScrollWindow(0, save - si.nPos); //scroll the window
}

【讨论】:

猜你喜欢
  • 2013-02-05
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
相关资源
最近更新 更多