65.9K
CodeProject 正在变化。 阅读更多。
Home

DSGraphEdit:.NET 中 Microsoft GraphEdit 的合理翻版

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (77投票s)

2007年10月30日

MIT

7分钟阅读

viewsIcon

327003

downloadIcon

9987

一个为 .NET 应用程序添加类似 Microsoft GraphEdit 功能的库

DSGraphEditDemo

引言

DSGraphEdit 是一个库,可以轻松地将类似于 Microsoft 经典的 GraphEdit 的功能添加到您的 .NET 应用程序中。大部分功能已被重新实现,并加入了一些新的特性,以辅助 DirectShow 软件的调试。

背景

GraphEditDirectShow SDK(后来移至 Windows SDK)附带的一个实用程序,它是一个用于创建和测试媒体播放过滤器图的可视化工具。GraphEdit 最强大的功能之一是通过 ROT(正在运行对象表)连接到外部应用程序中运行的过滤器图的能力。然而,这样做往往令人沮丧,因为它经常崩溃,并且在连接到远程图时只提供有限的功能。GraphEdit 的另一个缺点是它是闭源的,不能与您自己的软件自由分发。DSGraphEdit 使用 DirectShowLibMedia Foundation .NET(用于增强视频渲染器)和 DaggerLibDaggerLib 是一个有助于可视化构建和执行 DAG(有向无环图)以实现基于流的编程的库。这将在后续文章中更详细地介绍。

Using the Code

要在您自己的应用程序中使用 DSGraphEdit,请将对 lib 目录中的 DaggerLib.DSGraphEdit.dll 文件进行引用,并将命名空间添加到窗体中

//add namespace    
using DaggerLib.DSGraphEdit;

DaggerLib.DSGraphedit 提供了三个控件

  • DSGraphEditPanel:用于查看和操作过滤器图的画布。
  • DSFiltersPanel:一个面板,维护系统上注册的 DirectShow 过滤器的树状结构。
  • DSGraphEditForm:一个集成了 DSGraphEditPanelDSFiltersPanel 的多合一对话框,方便测试。

DSGraphEditPanel

构造 DSGraphEditPanel

DSGraphEditPanel 可以通过四种不同的方式创建

  1. // construct a DSGraphEditPanel with an empty IFilterGraph
    DSGraphEditPanel dsGraphEditPanel = new DSGraphEditPanel();
  2. // construct a DSGraphEditPanel from an existing IFilterGraph
    IFilterGraph myFilterGraph = (IFilterGraph)new FilterGraph();
    ...
    // do something with myFilterGraph
    ...
    DSGraphEditPanel dsGraphEditPanel = new DSGraphEditPanel(myFilterGraph);
  3. // construct a DSGraphEditPanel from a *.grf file
    // Grf files are files that are created by GraphEdit or from a call 
    // to DSGraphEditPanel.SaveFilterGraph(string filename). 
    // Also, constructing a DSGraphEditPanel from a grf file should 
    // always be enclosed in a try/catch block because 
    // it may want some filters that are not registered on your system. 
    
    DSGraphEditPanel dsGraphEditPanel = null;
    try
    {
        dsGraphEditPanel = new DSGraphEditPanel("c:\\somegraphfile.grf");
    }
    catch (Exception ex)
    {
        // we failed, show the error
    
        MessageBox.Show(ex.Message, "Error loading graph file");
    }
  4. // attempt connection to a remote graph on the ROT via 
    // the DSGraphEditPanel.ConnectToRemoteGraph static method
    DSGraphEditPanel dsGraphEditPanel = null;
    try
    {
        dsGraphEditPanel = DSGraphEditPanel.ConnectToRemoteGraph();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error connecting to remote graph");
    }
    ...
    // do something with your connected graph
    
    ...
    // disconnect from the Remote Graph
    
    dsGraphEditPanel.Dispose();
    dsGraphEditPanel = null;

DSGraphEditPanel.ConnectToRemoteGraph() 静态方法会弹出一个对话框,其中包含一个当前在 ROT 中注册的 IFilterGraph 列表,供用户选择。

Connecting to a Remote Graph

要断开与远程图的连接,只需调用 Dispose() 方法来释放 DSGraphEditPanel。此外,与从 *.grf 文件构造类似,ConnectToRemoteGraph 静态方法应始终包含在 try/catch 块中。

使用 DSGraphEditPanel

DSGraphEditPanel 由三个区域组成

DSGraphEditPanel Items

工具栏按钮
  • 播放按钮 运行过滤器图。对应的方法是 DSGraphEditPanel.Play()
  • 暂停按钮 暂停过滤器图。对应的方法是 DSGraphEditPanel.Pause()
  • 停止按钮 停止过滤器图。对应的方法是 DSGraphEditPanel.Run()
  • 逐帧跳过按钮 向前跳过一帧。对应的方法是 DSGraphEditPanel.StepOneFrame()
  • 刷新按钮 同步显示图与过滤器图的内容。如果认为画布的内容不能准确反映过滤器图的当前状态,请使用此按钮。对应的方法是 DSGraphEditPanel.SyncGraphs()
  • 自动布局按钮 自动排列显示图中的过滤器。对应的方法是 DSGraphEditPanel.ArrangeNodes()
  • 断开所有引脚按钮 断开过滤器图中的所有引脚连接。
  • 保存过滤器图按钮 将过滤器图保存到 *.grf 文件。这些文件与 Microsoft 的 GraphEdit 兼容。对应的方法是 DSGraphEditPanel.SaveFilterGraph(string filename)
  • 渲染媒体文件按钮 将媒体文件渲染到过滤器图中。对应的方法是 DSGraphEditPanel.RenderMediaFile(string filename)
  • 渲染 URL 按钮 将 URL(统一资源定位符)渲染到过滤器图中。对应的方法是 DSGraphEditPanel.RenderURL(string URL)
  • 面条样式按钮 提供了多种样式来显示过滤器之间的连接。对应的属性是 DSGraphEditPanel.NoodleStyle(是的,它们被称为“面条”)
    • Bezier:简单的贝塞尔曲线
    • Lines:五段线
    • CircuitBoardCoarse:所有直角(使用 A* 寻路算法)
    • CircuitBoardFine:与 CircuitBoardCoarse 相同,但允许非直角
    • Ramen:与 CircuitBoardFine 相同,但使用样条曲线而不是直线段
  • 图选项按钮 提供了过滤器图的多种操作和视觉样式
    • 阴影:过滤器和面条会在画布上投射阴影。对应的属性是 DSGraphEditPanel.DropShadow
    • 引脚放置:设置过滤器上的引脚是位于内部、外部还是缩进。对应的属性是 DSGraphEditPanel.PinPlacement
    • 显示引脚名称:将引脚名称绘制在画布上。对应的属性是 DSGraphEditPanel.ShowPinNames
    • 显示/隐藏时间滑块:设置时间滑块的可见性。对应的属性是 DSGraphEditPanel.ShowTimeSlider
    • 模态属性:设置过滤器是在模态对话框中显示其属性,还是直接在画布上显示。对应的属性是 DSGraphEditPanel.ModalProperties
    • 智能连接:设置过滤器图在连接两个引脚时是否添加中间过滤器。对应的属性是 DSGraphEditPanel.ConnectIntelligent
    • 使用时钟:启用或禁用过滤器图的参考时钟。对应的属性是 DSGraphEditPanel.UseReferenceClock
时间滑块

如果 filterGraph 具有 IMediaSeeking 功能,您可以通过时间滑块设置图的当前播放位置。与 Microsoft 的 GraphEdit 不同,时间滑块显示当前时间(以小时:分钟:秒:帧格式),并允许您设置媒体的开始和结束位置。

画布

Canvas 是过滤器显示为节点并通过面条相互连接的地方。连接引脚就像拖放或点击一样简单。此外,根据过滤器类型的不同,节点可以具有几种不同的属性。

如果 DSGraphEditPanel 被设置为 ModalProprties = false,点击 按钮将显示/隐藏节点内部过滤器的属性。这样,您可以在画布上同时打开多个过滤器属性。否则,过滤器属性将在模态对话框中显示。查看过滤器属性时,点击 **扫描接口** 按钮将扫描过滤器支持的所有已知 DirectShow 和 Media Foundation 接口,以及注册表中的任何接口,并将它们显示在一个对话框中供您查看。

如果 DSGraphEditPanel 是使用 DSGraphEditPanel()DSGraphEditPanel(string graphFileName) 构造函数创建的,并且过滤器是视频渲染器,则视频将在节点内部显示。要将视频分离到自己的窗口中,请单击“分离视频窗口”按钮 。关闭分离的视频窗口将返回到节点内的视频。此外,如果视频渲染器连接到任何 DVD 导航器过滤器,视频窗口将向导航器发送鼠标事件,从而实现与 DVD 菜单的交互。

与 Microsoft 的 GraphEdit 不同,DSGraphEditPanels 允许您查看和修改 DMO(DirectX 媒体对象)的属性。

DSGraphEditDemo DMO

DSFiltersPanel

DSFiltersPanel 提供了一个可搜索的 TreeView,其中包含系统中注册的所有 DirectShow 过滤器。构造 DSFiltersPanel 后,将其 AssociatedGraphPanel 属性设置为当前的 DSGraphEditPanel。一旦创建了 DSFilterPanel 并将其与 DSGraphEditPanel 关联,您就可以将过滤器拖放到 DSGraphEditPanel 上,双击它们将其添加到关联的 DSGraphEditPanel 中,或者点击“插入过滤器”按钮 DSFilterPanel 还提供了一个属性面板,其中包含注册表中找到的所有 FilterData 信息。

DSFiltersPanel

图导航器

图导航器提供了当前 DSGraphEditPanel 的小视图,其中有一个指示器显示视口中可见的画布部分。您可以拖动指示器以快速滚动图到新位置。

Graph Navigator

DSGraphEditForm

DSGraphEditForm 允许您快速查看过滤器图,而无需麻烦地设置 DSGraphEditPanel/DSFiltersPanel 对或连接到远程图。

// create an arbitrary IFilterGraph

IFilterGraph myFilterGraph = (IFilterGraph)new FilterGraph();
...
// do something with myFilterGraph

...
// create and show the DSGraphEditForm as a modal dialog

DSGraphEditForm dsGraphEditForm = new DSGraphEditForm(myFilterGraph);
dsGraphEditForm.ShowDialog();

// dispose of it

dsGraphEditForm.Dispose();
dsGraphEditForm = null;

简单快捷。

已知问题

为了让 DSGraphEditPanel.ConnectToRemoteGraph() 在 Windows Vista 上正常工作,您需要安装 Windows SDK for Windows Vista 中的 GraphEdit 版本,并注册它附带的 proppage.dll。如果您使用的是旧版 Windows SDK 中的旧版 GraphEdit,它仍然无法工作。它必须是 Windows SDK for Vista 中的版本。原因是 Microsoft(以其无限的智慧)在 Vista 的 Quartz.dll 中删除了几乎所有的代理/存根对,并将它们全部移到了 proppage.dll 文件中。如果没有注册代理/存根对,Windows 就无法在不同的线程单元之间编组代理。(微软,真可耻。)

历史

  • 2007/10/30:DSGraphEdit 初始发布
  • 2007/12/14:版本 1.1
    • DSGraphEdit 演示现在使用 Weifenluo DockPanel Suite 进行 MDI 风格的多图编辑。
    • DaggerLib.UI.Windows 的渲染速度进行了重大优化。
    • 现在已将 DaggerLib.CoreDaggerLib.UI.Windows 的完整源代码包含在解决方案中。
    • 添加了 GraphNavigator 控件,以便于编辑/浏览大型图。
    • 在不显示非模态属性时,引脚名称会绘制在节点内。
    • 排列节点 现在会考虑绘制在画布上的引脚名称。
    • 当加载包含未连接视频渲染器的图时,VideoInternalWindow 中的 InitVideoWindow 会失败。
    • VideoInternalWindow 现在支持加载包含 EVR 过滤器的图。
    • SyncGraph 现在会移除/重新路由连接。
    • VideoInternalWindow 会将鼠标位置和鼠标单击事件发送到连接的 DVD 导航器,以便与 DVD 菜单进行交互。
    • 托管连接到 DVD 导航器的 VideoInternalWindow 的过滤器节点现在具有 DVD 章节按钮。
    • VideoInternalWindow 现在支持窗口化全屏。
    • DSGraphEditPanel 添加了 CanvasImage 属性,用于检索画布的快照。
    • 现在会扫描所有接口,而不仅仅是 DirectShow 接口(引脚和过滤器都支持)。
    • 修复了一些在非模态模式下不显示的属性页。
  • 2018/1/20:版本 1.2
    • 修复了 64 位系统上 DaggerUIGraph.KeyboardProc 的问题
    • 在主窗体上添加了 64/32 位运行时指示
    • 添加了“作为 32 位运行”的项目
    • 许可证更改为 MIT
    • 更新了 MediaFoundationNetDirectShowLib 的版本
© . All rights reserved.