尽管 SIF_DISABLENOSCROLL 滚动条不可见
Scroll bar doesn't become visible despite SIF_DISABLENOSCROLL
考虑带有 WS_HSCROLL
and/or WS_VSCROLL
滚动条的 window。通常,如果滚动范围太小,Windows 会自动使这些滚动条不可见 (nPage <= nMax
)。
如果window当前由于滚动范围太小而处于滚动条不可见的状态,并且SetScrollInfo
带有SIF_DISABLENOSCROLL
标志用于force the scroll bars to be visible, but disabled,那么调用似乎没有任何效果。
如果在滚动条当前可见时设置 SIF_DISABLENOSCROLL
(由于滚动范围足够大),则它会按预期工作。
这里有一个简单的切换来演示这个问题:
SCROLLINFO ScrollInfo = {};
ScrollInfo.cbSize = sizeof(ScrollInfo);
if (WantScrollBarsVisible)
{
ScrollInfo.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_RANGE;
ScrollInfo.nPage = 100;
ScrollInfo.nMax = 1; // Smaller value than nPage, so that the scroll bars should be disabled
// NOTE: If nMax is bigger than nPage, the scroll bars do become visible as expected.
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
// Bugged!! Scroll bars are still invisible.
// They *happen* to become visible as soon as the window is being resized.
}
else
{
ScrollInfo.fMask = SIF_PAGE | SIF_RANGE;
// This makes the scroll bars effectively invisible (nMin == nMax == nPage == 0)
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
}
在 SetScrollInfo
之后调用 ShowScrollBar(..., true)
也不起作用。 InvalidateRect
或 UpdateWindow
.
也没有
有趣的是,也没有 WM_SIZE
消息,正如您在 SetScrollInfo
调用后通常预期的那样,因为如果滚动条出现(或消失),客户区会缩小。
这似乎是 Windows 中的错误。
https://microsoft.public.vc.mfc.narkive.com/7gXZ62cm/sif-disablenoscroll
事实证明,如果滚动条 当前不可见 无论出于何种原因 (1),请使用 SetScrollInfo
与 SIF_DISABLENOSCROLL
永远不会让它可见。
之所以最初有效,是因为在window创建时,滚动条恰好有一些默认值,可以使其可见。调整 window 的大小也恰好使滚动条可见,如果它们错误地不可见的话。可能是部分系统更新了一堆滚动参数,然后突然意识到滚动条毕竟应该是可见的。
上面的文章包含一个解决方法:在使用 SetScrollInfo
和 SIF_DISABLENOSCROLL
之前,首先设置一些滚动参数(使用 SetScrollInfo
和 而没有 SIF_DISABLENOSCROLL
) 肯定 会导致显示滚动条。您需要每次您认为滚动条可能目前不可见。
我发现这很尴尬,想出了这个:
SCROLLINFO ScrollInfo = {};
ScrollInfo.cbSize = sizeof(ScrollInfo);
if (WantScrollBarsVisible)
{
// ======================================================================
// Use ShowScrollBar to ensure that the scroll bars are visible *BEFORE*
// calling SetScrollInfo with SIF_DISABLENOSCROLL.
ShowScrollBar(hWnd, SB_VERT, true);
ShowScrollBar(hWnd, SB_HORZ, true);
// ======================================================================
ScrollInfo.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_RANGE;
ScrollInfo.nPage = 100;
ScrollInfo.nMax = 1; // Smaller value than nPage, so that the scroll bars should be disabled
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
}
else
{
ScrollInfo.fMask = SIF_PAGE | SIF_RANGE;
// This makes the scroll bars effectively invisible (nMin == nMax == nPage == 0)
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
}
通常,ShowScrollBar
不是很有用,因为它的效果是不稳定的 - 只要使用 SetScrollInfo
更改滚动参数,它们就会被覆盖。但是,在这种情况下,只要确保在 SIF_DISABLENOSCROLL
出现之前滚动条可见就足够了。
如果可以直接与滚动条交互,甚至可能有更好的方法(比如告诉他们立即更新自己)。
(1) 我测试过的可能原因包括: Window styles WS_VSCROLL
/WS_HSCROLL
being removed从 window 创建后;以前 nMax-nMin<=nPage
(滚动范围太小)没有 SIF_DISABLENOSCROLL
; ShowScrollBar(..., false)
.
考虑带有 WS_HSCROLL
and/or WS_VSCROLL
滚动条的 window。通常,如果滚动范围太小,Windows 会自动使这些滚动条不可见 (nPage <= nMax
)。
如果window当前由于滚动范围太小而处于滚动条不可见的状态,并且SetScrollInfo
带有SIF_DISABLENOSCROLL
标志用于force the scroll bars to be visible, but disabled,那么调用似乎没有任何效果。
如果在滚动条当前可见时设置 SIF_DISABLENOSCROLL
(由于滚动范围足够大),则它会按预期工作。
这里有一个简单的切换来演示这个问题:
SCROLLINFO ScrollInfo = {};
ScrollInfo.cbSize = sizeof(ScrollInfo);
if (WantScrollBarsVisible)
{
ScrollInfo.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_RANGE;
ScrollInfo.nPage = 100;
ScrollInfo.nMax = 1; // Smaller value than nPage, so that the scroll bars should be disabled
// NOTE: If nMax is bigger than nPage, the scroll bars do become visible as expected.
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
// Bugged!! Scroll bars are still invisible.
// They *happen* to become visible as soon as the window is being resized.
}
else
{
ScrollInfo.fMask = SIF_PAGE | SIF_RANGE;
// This makes the scroll bars effectively invisible (nMin == nMax == nPage == 0)
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
}
在 SetScrollInfo
之后调用 ShowScrollBar(..., true)
也不起作用。 InvalidateRect
或 UpdateWindow
.
有趣的是,也没有 WM_SIZE
消息,正如您在 SetScrollInfo
调用后通常预期的那样,因为如果滚动条出现(或消失),客户区会缩小。
这似乎是 Windows 中的错误。
https://microsoft.public.vc.mfc.narkive.com/7gXZ62cm/sif-disablenoscroll
事实证明,如果滚动条 当前不可见 无论出于何种原因 (1),请使用 SetScrollInfo
与 SIF_DISABLENOSCROLL
永远不会让它可见。
之所以最初有效,是因为在window创建时,滚动条恰好有一些默认值,可以使其可见。调整 window 的大小也恰好使滚动条可见,如果它们错误地不可见的话。可能是部分系统更新了一堆滚动参数,然后突然意识到滚动条毕竟应该是可见的。
上面的文章包含一个解决方法:在使用 SetScrollInfo
和 SIF_DISABLENOSCROLL
之前,首先设置一些滚动参数(使用 SetScrollInfo
和 而没有 SIF_DISABLENOSCROLL
) 肯定 会导致显示滚动条。您需要每次您认为滚动条可能目前不可见。
我发现这很尴尬,想出了这个:
SCROLLINFO ScrollInfo = {};
ScrollInfo.cbSize = sizeof(ScrollInfo);
if (WantScrollBarsVisible)
{
// ======================================================================
// Use ShowScrollBar to ensure that the scroll bars are visible *BEFORE*
// calling SetScrollInfo with SIF_DISABLENOSCROLL.
ShowScrollBar(hWnd, SB_VERT, true);
ShowScrollBar(hWnd, SB_HORZ, true);
// ======================================================================
ScrollInfo.fMask = SIF_DISABLENOSCROLL | SIF_PAGE | SIF_RANGE;
ScrollInfo.nPage = 100;
ScrollInfo.nMax = 1; // Smaller value than nPage, so that the scroll bars should be disabled
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
}
else
{
ScrollInfo.fMask = SIF_PAGE | SIF_RANGE;
// This makes the scroll bars effectively invisible (nMin == nMax == nPage == 0)
SetScrollInfo(hWnd, SB_VERT, &ScrollInfo, true);
SetScrollInfo(hWnd, SB_HORZ, &ScrollInfo, true);
}
通常,ShowScrollBar
不是很有用,因为它的效果是不稳定的 - 只要使用 SetScrollInfo
更改滚动参数,它们就会被覆盖。但是,在这种情况下,只要确保在 SIF_DISABLENOSCROLL
出现之前滚动条可见就足够了。
如果可以直接与滚动条交互,甚至可能有更好的方法(比如告诉他们立即更新自己)。
(1) 我测试过的可能原因包括: Window styles WS_VSCROLL
/WS_HSCROLL
being removed从 window 创建后;以前 nMax-nMin<=nPage
(滚动范围太小)没有 SIF_DISABLENOSCROLL
; ShowScrollBar(..., false)
.