在WTL中实现自定义绘制控件中的滚动

Ale*_*ruC 3 winapi wtl atl visual-c++

我已经创建了我自己的自定义绘制列表与复选框WTL,我想让它现在可滚动,事情是,我正在子类化我绘制的静态文本控件..我不知道静态控件是否支持任何滚动方式..无论如何我的问题是如何使我的自定义控件可滚动,我是否必须自己强制机制?

Cod*_*ray 5

是的,你必须完全手工实施.这是不使用内置控件的缺点.从ListBox开始然后根据您的需求自定义它可能是一个更好的主意.这样,您就可以免费获得所有滚动,选择和其他逻辑.

步骤大致如下(部分或全部可能有ATL/WTL惯用法,但任何ATL/WTL程序员都可以从原始Win32来回转换):

  1. WS_HSCROLL和/或WS_VSCROLL窗口样式添加到自定义静态控件,具体取决于您是否需要水平,垂直或两个滚动条.您可以将这些添加到传递给CreateWindow/CreateWindowEx函数的窗口样式列表中.

  2. 默认情况下,这些滚动条根本不会执行任何操作.你需要告诉他们使用这个SetScrollInfo功能做什么.在你的情况下:

    • 第一个参数(hwnd)将是控件窗口的句柄.
    • 第二个参数(fnBar)应该是SB_HORZ调整水平滚动条,或SB_VERT调整垂直滚动条.
    • 第三个参数(lpsi)是一个指向SCROLLINFO结构的指针,用所需的滚动参数填充,包括拇指的当前位置,最小值和最大值,以及用于设置比例滚动条的"页面"大小.
    • 第四个参数(fRedraw)应该设置为TRUE.

  3. 您还需要该EnableScrollBar功能以根据需要启用/禁用滚动条.像以前的功能一样,

    • hwnd 是控制窗口的句柄
    • wSBflags或者是SB_HORZ,SB_VERT,或SB_BOTH
    • wArrowsESB_*值之一,取决于你想要的

  4. 最后,您需要在自定义控件的窗口过程中编写代码来处理WM_HSCROLL和/或WM_VSCROLL消息.每当移动滚动条时,都会将它们发送到窗口.在这些消息的处理程序内部,您将需要执行以下操作来更新控件的状态:

    • 调用该SetScrollInfo函数将拇指更新到新位置
    • 根据滚动距离重绘控件的内容.有多种方法可以做到这一点,但我可能会使用这个ScrollWindowEx功能.

    自定义控件的窗口过程需要处理WM_SIZE消息以更新滚动条状态(通过调用SetScrollInfo和/或EnableScrollBar)以响应窗口大小的变化.


Rom*_* R. 5

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
Run Code Online (Sandbox Code Playgroud)

没有太多的代码/片段来演示使用,但仍然有一个WTL示例涵盖了基础知识,它也应该是一个很好的起点.\Samples\BmpView有一个可滚动位图的类:

class CBitmapView : 
  public CScrollWindowImpl<CBitmapView>
{
public:
Run Code Online (Sandbox Code Playgroud)

你会发现它非常小,它涵盖了大部分的复杂性.

  • "人们现在用什么来用C++创建完全自定义的界面".我喜欢WTL,但它绝对不是主流.我认为主流是跨平台的UI框架,通常会产生丑陋的UI和糟糕的用户体验,而.NET则远不及C++. (3认同)