如何在 vc++ win32 中制作可滚动窗口

Posted

技术标签:

【中文标题】如何在 vc++ win32 中制作可滚动窗口【英文标题】:how to make a scrollable window in vc++ win32 【发布时间】:2015-09-18 14:55:55 【问题描述】:

基本上我在自定义窗口中有一个滚动条,我们可以在其中添加其他控件,如按钮、文本框等,现在这是我创建滚动条的问题,它可以向下和向上滚动,但问题是应该指定最大滚动,然后阻止它滚动更多,但是可以有用户想要的尽可能多的控制,这对我来说是未知的,我的意思是想告诉问题更像是一个文本框当您使用 WM_VSCROLL 或 HSCROLL 指定它时,内置滚动条,然后让用户能够滚动您在文本框中键入的内容,这正是我想要的。 这是到目前为止我能够通过的代码:-

滚动条代码:-

case WM_LBUTTONDOWN:
    
            SCROLLINFO si =  0 ;
            si.cbSize = sizeof(SCROLLINFO);
            si.fMask = SIF_POS;
            si.nPos = 0;
            si.nTrackPos = 0;
            GetScrollInfo(hwnd, SB_VERT, &si);
            break;
    
     case WM_VSCROLL:
    
            auto action = LOWORD(wParam);
            HWND hScroll = (HWND)lParam;
            int pos = -1;
            if (action == SB_THUMBPOSITION || action == SB_THUMBTRACK) 
                    pos = HIWORD(wParam);
             else if (action == SB_LINEDOWN) 
                    pos = g_scrollY + 50;
             else if (action == SB_LINEUP) 
                    pos = g_scrollY - 50;
             else if (action == SB_PAGEUP) 
                    GetClientRect(hwnd, &r);
                    pos = g_scrollY - r.bottom;
             else if (action == SB_PAGEDOWN)
                    GetClientRect(hwnd, &r);
                    pos = g_scrollY + r.bottom;
            
            if (pos == -1)
                    break;
            SCROLLINFO si =  0 ;
            si.cbSize = sizeof(SCROLLINFO);
            si.fMask = SIF_POS;
            si.nPos = pos;
            si.nTrackPos = 0;
            SetScrollInfo(hwnd, SB_VERT, &si, true);

            GetScrollInfo(hwnd, SB_VERT, &si);
            pos = si.nPos;
            POINT pt;
            pt.x = 0;
            pt.y = pos - g_scrollY;
            auto hdc = GetDC(hwnd);
            LPtoDP(hdc, &pt, 1);
            ReleaseDC(hwnd, hdc);
            ScrollWindow(hwnd, 0, -pt.y, NULL, NULL);
            g_scrollY = pos;
            return 0;
    
case WM_SIZE:
    
            RECT rc =  0 ;
            GetClientRect(hwnd, &rc);
            SCROLLINFO si =  0 ;
            si.cbSize = sizeof(SCROLLINFO);
            si.fMask = SIF_ALL;
            si.nMin = 0;
            si.nMax = MAX_RANGE;
            if(si.nPos > 100)
                si.nMax = 5000;
            if(SB_THUMBPOSITION == 100)

                si.nMax = MAX_RANGE;
            si.nPage = (rc.bottom - rc.top);
            si.nPos = 0;
            si.nTrackPos = 0;
            SetScrollInfo(hwnd, SB_VERT, &si, true);
            break;
    

你可以看到 si.nMax 值是它能够滚动的最大行数,但我希望它和控件一样多。

【问题讨论】:

您可能需要考虑使用 GUI 框架,如 wxWidgets、Qt 等。 @ThomasMatthews:wxWidgets 可能几乎无法使用。另一方面,Qt 是如此的糟糕,以至于你不可能想要推荐它。甚至 MFC 也能产生更好的 GUI,这说明了很多。除此之外,问题是关于 Windows API 编程的,可滚动窗口当然不是寻找框架的理由。 如果要求框架推荐对 SO 来说是题外话,那么建议他们也应该这样做。 【参考方案1】:

您必须知道窗口中有多少控件,因此您可以将 SCROLLINFO 结构中的 nMax 成员设置为您想要的任何值,并在添加新控件时调用 SetScrollInfo()。

【讨论】:

好的,您将如何计算,用户必须在该自定义窗口的静态控件中显示多少张图片。 @alasenburgers:通过应用数学。 我的数学真的很差,但我想我有另一个想法,我的意思是你可以告诉我扩展 si.nMax 值,就像用户向上滚动以结束 si.nMax价值应该扩展什么的 或者我们可以得到最后一个控件的位置并将最大值设置为那么多,没有你的帮助我绝对做不到 嘿,谁能告诉我如何扩展它,是吗?

以上是关于如何在 vc++ win32 中制作可滚动窗口的主要内容,如果未能解决你的问题,请参考以下文章

如何在WIN32 API中“通知”父窗口有关子窗口“列表框”控件的“滚动事件”?

VC++ win32 application里如何建一个子窗口

如何在win32编程中,在同一个窗口下播放多个音乐

VC MFC中如何制作无边框窗口

VC中怎么滚动条宽度怎么解决

在 Win32API 中注册一个窗口类