【发布时间】:2013-08-12 22:26:32
【问题描述】:
我已经用 WTL 中的复选框创建了我自己的自定义绘制列表,我现在想让它可滚动,问题是我正在继承我绘制的静态文本控件。我不知道静态控件是否支持以任何方式滚动.. 无论如何,我的问题是如何使我的自定义控件可滚动,我是否必须自己实现该机制?
【问题讨论】:
标签: winapi visual-c++ atl wtl
我已经用 WTL 中的复选框创建了我自己的自定义绘制列表,我现在想让它可滚动,问题是我正在继承我绘制的静态文本控件。我不知道静态控件是否支持以任何方式滚动.. 无论如何,我的问题是如何使我的自定义控件可滚动,我是否必须自己实现该机制?
【问题讨论】:
标签: winapi visual-c++ atl wtl
是的,您必须完全手动实现它。这是不使用内置控件的缺点。从 ListBox 开始,然后根据您的需要对其进行自定义可能是一个更好的主意。这样一来,您就可以免费获得所有的滚动、选择和其他逻辑。
步骤大致如下(其中部分或全部可能有 ATL/WTL 惯用语,但任何 ATL/WTL 程序员都可以从原始 Win32 来回转换):
将WS_HSCROLL 和/或WS_VSCROLL 窗口样式添加到您的自定义静态控件中,具体取决于您是否需要水平、垂直或两个滚动条。您可以将这些添加到传递给 CreateWindow/CreateWindowEx 函数的窗口样式列表中。
默认情况下,这些滚动条根本不会做任何事情。您需要使用SetScrollInfo 函数告诉他们该做什么。在你的情况下:
hwnd) 将是您的控制窗口的句柄。fnBar)应该是SB_HORZ来调整水平滚动条,或者SB_VERT来调整垂直滚动条。lpsi)是一个指向SCROLLINFO结构的指针,填充了所需的滚动参数,包括拇指的当前位置、最小值和最大值,以及使用的“页面”大小设置比例滚动条。fRedraw)可能应该设置为TRUE。
您还需要EnableScrollBar 函数来根据需要启用/禁用滚动条。和之前的函数一样,
hwnd 是控制窗口的句柄wSBflags 是 SB_HORZ、SB_VERT 或 SB_BOTH
wArrows 是 ESB_* 值之一,具体取决于您想要什么
最后,您需要在自定义控件的窗口过程中编写代码来处理WM_HSCROLL 和/或WM_VSCROLL 消息。每当滚动条移动时,它们就会发送到窗口。在这些消息的处理程序中,您需要执行以下操作来更新控件的状态:
SetScrollInfo 函数将拇指更新到新位置ScrollWindowEx 函数。
自定义控件的窗口过程也需要处理WM_SIZE消息来更新滚动条状态(通过调用SetScrollInfo和/或EnableScrollBar)以响应变化窗口的大小。
【讨论】:
CScrollImpl,它涵盖了自定义控件的大量复杂性。
Cody Gray 为添加滚动支持提供了出色的介绍,但是您还拥有 WTL 本身的帮助。
WTL 的atlscrl.h 为您提供类来继承和实现带有滚动的自定义窗口/控件。
// Classes in this file:
//
// CScrollImpl<T>
// CScrollWindowImpl<T, TBase, TWinTraits>
// CMapScrollImpl<T>
// CMapScrollWindowImpl<T, TBase, TWinTraits>
// CFSBWindowT<TBase>
// CZoomScrollImpl<T>
// CZoomScrollWindowImpl<T, TBase, TWinTraits>
// CScrollContainerImpl<T, TBase, TWinTraits>
// CScrollContainer
没有太多的代码/sn-ps 来演示使用,但仍然有一个涵盖基础知识的 WTL 示例,它也应该是一个很好的起点。 \Samples\BmpView 有一个可滚动位图的类:
class CBitmapView :
public CScrollWindowImpl<CBitmapView>
{
public:
您会发现它非常小,而且涵盖了大部分复杂性。
【讨论】: