【问题标题】:C++ Winapi Owner drawn listbox animationC++ Winapi Owner 绘制的列表框动画
【发布时间】:2015-10-13 17:28:44
【问题描述】:

我有一个所有者绘制的列表框,我想在其中绘制一些进度的动画。我相信一张我到目前为止所拥有的照片会说明很多:

每个文件在拖放到 DRAG HERE 区域时都会添加到列表框中,这里会创建一个新线程并启动加密/解密过程。 enc/dec 过程将进度值(以百分比为单位)保存到给定的变量中,即完成了多少工作。
随着进度的增加,我正在重新绘制列表框。

if(progress - prevProgress > 1.0)
{
    InvalidateRect(Listbox, &ListboxProgressRect, TRUE);
    UpdateWindow(Listbox);
    prevProgress = progress;
}

问题在于即使只需要重绘一项,也会重绘每一项。ListboxProgressRect 区域实际上包括列表框最右边的 40 像素乘以列表框高度。

我想用子类 Ctrl 完全在 WM_PAINT 中处理绘图,但我不知道如何绘制项目和滚动条功能。 进度条旁边的编辑框和按钮也不错。

我应该继承列表框并处理所有绘图吗?如果是这样,我该如何绘制滚动条(并使其工作)?

【问题讨论】:

    标签: c++ winapi listbox ownerdrawn


    【解决方案1】:

    您只想重绘一项,因此您应该只使一项无效。

    问题是,你不知道物品在哪里。列表框可以。所以问问吧。

    发送LB_GETITEMRECT

    【讨论】:

    • 这正是我想要的,非常感谢!
    【解决方案2】:

    有多少线程可以处理您的列表框?我想使用 theards 是个坏主意。最好为整个列表框使用计时器,检查每个可见元素的状态并检查它是否必须重绘。使用 InvalidateRect 强制 WM_PAINT 重绘列表。

    线程只会使您的代码复杂化。

    为了避免处理绘图scrobars,不要子类化列表,而是创建一个onwerdrawn列表框,它很灵活,也可以处理滚动平滑。

    【讨论】:

    • 线程用于加密/解密文件,因此它们是必要的。到最后一段,请再看一下我的问题 - 我没有子类列表框,但 ownerdrawn。
    • 好的,所以从绘制列表框中排除线程,将任务分配给他们只更新项目状态。并让计时器在需要时重新绘制项目。 (使用临界区来更新项目的状态。)
    • 我尽可能少地重绘列表框,这就是为什么我在运行加密的线程中调用InvalidateRect。每当加密过程完成其工作的 1% 时,它就会重新绘制列表框。有了一些计时器,即使不需要,我也必须每次都重新粉刷它。
    • 每一项的数据应该是一个结构体。对?向结构中添加一个名为 let say 'Dirty' 的成员,该成员将在状态更改时由线程设置,如果设置了 Dirty 标志,则计时器检查每个可见项目,如果设置了则调用 InvalidateRect 但不调用 UpdateWindow。 ON WM_DRAW 将所有绘制的项目标志(脏)重置为 0;在计时器检查结束时,如果找到(设置)任何标志,它可以调用 UpdateWindow
    • 另一种可能性是使用现有成员(progress & prevProgress)来检查项目是否脏;在 WM_PAINT 中设置 prevProgress=progress 绘制完成时
    猜你喜欢
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多