如何使用米字形进度条?

10
在Vista/7中,Windows资源管理器窗口使用一种特殊的静态进度条来显示硬盘空间。默认情况下,此进度条为蓝色且非动画。当接近满时(磁盘空间不足),它也会变成红色。
通过发送消息,我可以告诉Windows Forms ProgressBar控件将其状态更新为已暂停和错误(分别为黄色和红色),这很好用,但这些仍然是特定于进度的。
Windows用户体验指南中,它特别指出了进度条的这种“米”变体:

这种模式不是进度条,但它是使用进度条控件实现的。米具有与真正的进度条不同的外观。

他们说它“是使用进度条控件实现的”,那么...如何?我可以向控件发送什么消息,让它以这种方式运行?
我看到您可以发送设置条形颜色的消息,但文档说当启用视觉样式时,这些调用将被忽略。Windows API文档中ProgressBar控件的其他内容似乎没有建议如何做到这一点。我是否只能制作自定义绘制的条形图?我非常希望尽可能利用操作系统,以便应用程序在不同的操作系统版本中保持一致。我知道早于Vista的版本可能不支持此功能。

我正在寻找一个Windows Forms解决方案,但我想知道它是否通过Win32 API完全暴露出来。


回顾过去几年,就我个人而言,微软网页上的那些指南已经过时了,即使在它们发布时也被广泛忽略;它们的很多建议都非常应用和行业特定,其中一些现在看起来更像是为了宣传新的、闪亮的Windows Vista UX功能(当Windows 8推出时,微软后来谴责这些功能为俗气和过时)。如果您决定忽略其中一些指南,不必担心UX警察会写罚单。我仍然看到有大量进度条作为计量器使用。 - jrh
1个回答

11

这是可能的,但不能通过ProgressBar实现。Win7也不使用进度条来绘制这些仪表,因为没有与该进度条关联的窗口句柄。它必须使用自定义绘图。在WinForms中也可以使用VisualStyleRenderer类进行自定义绘制。然而,一件事情并没有帮助,即所需的视觉样式部件和状态没有声明,甚至在.NET 4.0中也是如此。

此示例窗体可复制仪表栏:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }
    VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.ProgressBar.Bar.Normal);
    protected override void OnPaint(PaintEventArgs e) {
      renderer.SetParameters("PROGRESS", 11, 2);
      renderer.DrawBackground(e.Graphics, new Rectangle(10, 10, 200, 15));
      renderer.SetParameters("PROGRESS", 5, 4);
      renderer.DrawBackground(e.Graphics, new Rectangle(10, 10, 100, 15));
    }
  }
}

我从 vsstyle.h SDK 头文件中获取了部件和状态编号。


对于任何感兴趣的人,你可以在%ProgramFiles%\Microsoft SDKs\Windows\vx.xx\Include中找到vsstyle.h,其中vx.xx是安装的任何版本SDK(你可能有几个)。http://en.wikipedia.org/wiki/Microsoft_Windows_SDK - Sean Hanley
1
还应该指出,对于那些无法复现这个问题的人来说:请注意,这是绘制在背景上的。如果你有面板或其他容器,你会希望渲染器在它们的绘制事件上进行绘制,而不是在窗体上进行绘制。否则,面板会重叠,并且正如你现在应该知道的那样,面板实际上并不透明,所以看起来好像你的条形图没有被渲染出来。 - Sean Hanley
当我尝试运行此代码时,我在 renderer.SetParameters("PROGRESS", 11, 2); 这一行收到了 当前视觉样式未定义给定类、部件和状态的组合 的错误信息。 - Matthew
1
我将此标记为答案,尽管对于 Windows 8,第二次调用 SetParameters 和 DrawBackground 只会绘制一个蓝色矩形。 - shellscape

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接