• 在。net中定制OpenFileDialog


    介绍 几天前,我想开始创建一个图标编辑器应用程序来利用我IconLib图书馆。 我创建了我的主要形式,我想“我要从哪里开始”。然后,我决定创建a 与开放的功能菜单。我认为开放特性之前,应该有一个预览屏幕看到图标打开它。 如果你正在读这一页,可能是因为你知道。net OpenFileDialog类,但它不能定制。这种控制的目的是允许您添加一些功能OpenFileDialog。net类。你不能定制的主要原因。net是因为班上OpenFileDialog声明密封这意味着你不能继承它。如果你去基类FileDialog,它将允许您继承它,但是有一个内部抽象方法“RunFileDialog”。因为它是内部和抽象,它只允许继承里面相同的装配。 有多少次你想把一些额外的控制OpenFileDialog控制和你不能… 寻找。net代码时,我发现他们使用MFC的地方,但没有为。net。OpenFileDialog不是本机在。net实现,相反,它使用了一个Win32 API“GetOpenFileName”。 MSDN 在这一点上,我有三个选择: 从头开始创建自己的OpenFileDialog。 创建我自己的OpenFileDialog重用资源,(使用API“GetOpenFileName”和提供自己的模板)。 黑客。net OpenFileDialog并添加我需要的功能。 选项(一)对我来说不是一个选择,因为它可能需要大量的开发时间,当我有更多的事情要做。后,产品完成后,我可以检查它。下一个选项需要我提供我自己的模板使用Win32 API调用和资源。选项(c)是更可行的选择在这个时间;不认为这是一个糟糕的黑客,黑客基本上是当你想要控制做一些额外的功能,你必须从一个不同的线程或进程。 因为我喜欢挑战,我决定“黑客”OpenFileDialog类来创建自己的定制的控制。 它可以帮你做什么 我可以砍控制去做我需要会这样,但我遇到了这个问题很多次从。net 1.0,没有人到目前为止已经有一个解决方案,所以我决定创建一个接口控制,它可用于不同的应用程序。 同时,我想创造一些东西,不需要更改或添加代码当前项目,并能够添加多个控件不知道它们是如何工作的详细信息;它需要一个独立的控制一样,可以添加其他的IDE。 我创建了这个控件,我称之为“OpenFileDialogEx”。 我怎么做吗? OpenFileDialogEx想象成一个抽象类:我不让这类抽象的唯一原因是因为VS IDE不能创建一个抽象类的一个实例,避免了呈现在屏幕上。 你可以使用OpenFileDialogEx类但毫无意义,因为它不包含任何额外的功能,只是一个空的用户控件。 所以你必须继承OpenFileDialogEx来创建您自己的自定义版本的打开文件对话框。 继承OpenFileDialogEx之后,您已经创建了一个自定义控件,您可以添加任何控制,你可以添加额外的按钮、面板、或一组框。基本上,它是一个容器控件;后来这个容器将“追加”。net OpenFileDialog动态对象。 有三个额外的属性,三种方法,和两个事件控制,不同于任何用户控件。 DefaultViewMode: 这个属性允许您选择哪种观点OpenFileDialog应该开始;默认情况下,它使用“细节视图”打开。在这里你可以指定一个不同的默认视图像图标,列表,缩略图,细节等。 StartLocation: 这个属性告诉如果创建的控制应堆放在右边,底部,或在经典OpenFileDialog后面。通常情况下,此属性将用于扩大OpenFileDialog水平。如果相反,你需要添加额外的控制当前OpenFileDialog,那么您可以指定“没有”和控制内部OpenFileDialogEx将共享相同的客户区与原OpenFileDialog。 OpenDialog: 此属性内部的嵌入式OpenFileDialog控制。在这里你可以设置标准属性InitialDir, AddExtension,过滤器等。 OpenFileDialog违约是可调整大小的,OpenFileDialogEx将帮助您自动;用户控制“OpenFileDialogEx”将自动调整大小。当用户扩展或收缩的窗口,它取决于StartLocation属性上的表现也不同。 StartLocation 右:用户控件将垂直缩放。 底部:用户控件将调整水平。 没有:用户控件将水平和垂直大小。 基本上,当你一个你必须设置每个控件的锚定属性,然后当用户调整OpenFileDialog窗口的大小时,你可以控制控件的位置。 例如,要进行图像预览,你可以在右侧设置开始位置,在继承的OpenFileDialogEx中添加一个PictureBox,并将PictureBox的锚定属性设置为左、上、右、下;这将在用户调整OpenFileDialog大小时动态调整图片框的大小。 这些方法是虚拟方法,您将覆盖它们以与原始OpenFileDialog交互。 OnFileNameChanged () 每当用户单击视图中的任何文件时,都会调用此方法。 OnFolderNameChanged () 每当用户更改OpenFileDialog中任何控件中的文件夹时,都会调用此方法。 OnClosing () 这个方法在OpenFileDialog关闭时被调用,这对于释放分配的资源很有用。 这两个事件是FileNameChanged和FolderNameChanged,这些事件是由它们各自的虚拟方法“OnFileNameChanged”和“OnFolderNameChanged”触发的。我建议重写方法,而不是使用事件,因为它是干净的代码,而且它没有另一层间接。 it 是怎么做的? 第一个问题是OpenFileDialog是一个模态对话框。这意味着您基本上无法获得窗口的句柄,因为当您调用ShowDialog()时,只要OpenFileDialog是打开的,您就无法控制程序流。 获得OpenFileDialog句柄的一种方法是覆盖窗体上的WndProc方法,并注意消息。当OpenFileDialog被创建时,所有者表单将收到一些消息,如WM_IDLE, WM_ACTIVATE, WM_NC_ACTIVATE,等等。这些消息将使用OpenFileDialog窗口的句柄来设置参数lParam。 如您所见,这需要重写WndProc方法。有些开发人员甚至不知道WndProc的存在,所以我想避免它。也。我注意到一些MDI窗口打开OpenFileDialog的问题。 然后我所做的是,当ShowDialog()被调用时,它在屏幕外创建了一个虚拟表单并隐藏了它,这个表单将负责打开OpenFileDialog并获取OpenFileDialog窗口句柄。 起初,它监听了WM_IDLE消息,但问题是,当消息发送时,已经太晚了,窗口被创建并显示在屏幕上。尽管如此,您仍然可以更改内容,但用户将看到原始OpenFileDialog和定制版本之间的屏幕上有一个小的闪烁。 相反,我们可以采取消息WM_ACTIVATE发生在OpenDialog显示在屏幕上。 到目前为止,它得到了句柄并准备好显示了,现在呢? 它将如何改变OpenFileDialog窗口的属性? 这时就出现了方便的。net NativeWindow, NativeWindow是一个窗口包装器,它处理关联到它的句柄发送的消息。它创建一个NativeWindow并将OpenFileWindow句柄关联到它。从这里开始,每个发送到OpenFileWindow的消息都将被重定向到我们自己的WndProc方法,我们可以取消、修改或者让它们通过。 在我们的WndProc中,我们处理消息WM_WINDOWPOSCHANGING。如果打开对话框正在打开,那么我们将根据用户设置的StartLocation改变原始的水平或垂直大小。它将增加要创建的窗口的大小。这只在控件打开时发生一次。 此外,我们将处理消息WM_SHOWWINDOW。在这里,原始OpenFileDialog中的所有控件都被创建,我们将把我们的控件“追加”到open file对话框中。这是通过调用Win32 API的“SetParent”来实现的。这个API允许您更改父窗口。然后,基本上它所做的是将我们的控件“附加”到它设置的位置中的原始OpenFileDialog,这取决于StartLocation属性的值。 它的优点是我们仍然可以完全控制附加到OpenFileDialog窗口的控件。这意味着我们可以接收事件,调用方法,并对这些控件做任何我们想做的事情。 同样,在初始化过程中,我们将获得原始OpenFileDialog中每个控件的窗口句柄。这再次允许创建。net NativeWindows来处理每个控件中的消息。 现在一切都准备好了,当用户点击ListView时,我们如何观察消息呢? 起初,我试图处理来自ListView本身的消息,为它创建一个本地窗口,但问题是,每次用户更改文件夹或单击不同的视图,处理程序被销毁,我们必须重新创建处理程序。 用MS Spy分析FileOpenDialog内的所有窗口,我们可以注意到FileOpenDialog内还有另一个文件对话框窗口,很可能是FileOpenDialog的基本窗口。检查MSDN文档中,我们看到在FileOpenDialog上所做的每一个动作都会触发一个WM_NOTIFY消息来填充一个OFNOTIFY结构;这个结构体包含所做操作的代码,其中两个操作是CDN_SELCHANGE和CDN_FOLDERCHANGE。 MSDN 当用户与文件夹组合框或列表视图交互时,将调用它们。然后,首先我获得了基文件窗口的句柄,并从这个句柄创建了一个NativeWindow。这允许处理消息WM_NOTIFY来分析OFNOTIFY结构和进程CDN_SELCHANGE和CDN_FOLDERCHANGE。当这个窗口处理这些消息时,它们被转发到OpenFileDialogEx控件的方法OnFileNameChanged和OnFolderNameChanged。 另一种方法是在关闭FileOpenDialog窗口时进行拦截。起初,我使用了消息WM_CLOSE,它工作,但后来我发现,这条消息没有被调用时,用户双击一个文件在列表视图。通过观察FileOpenDialog产生的消息,我发现我可以使用WM_IME_NOTIFY消息。当FileOpenDialog被关闭时,该消息以IMN_CLOSESTATUSWINDOW的wParam值发送;下面是我们对OnClosingDialog()方法的调用。 现在,当用户调整FileOpenDialog大小时,如何调整UserControl的大小;这是通过处理消息WM_WINDOWPOSCHANGING;在这里,我们指定相对于FileOpenDialog大小更改控件的大小。 作为一个重要的细节,当OpenFileWindow关闭时,它必须恢复到我们打开它时的原始大小,这是可能的,因为OpenFileWindow记住了最后的位置/大小。如果我们不这样做,每次打开OpenFileDialog时,它将增加大小,使其越来越大。 结论 我在Windows XP上进行了测试,它运行得很好,我没有机会在Windows 2000/2003或Vista等不同的操作系统上进行测试,但它应该可以正常工作,没有问题。我不认为它将工作在Windows 95/98,因为我设置的结构大小只匹配WinNT操作系统。如果您有任何评论或发现bug,请告诉我,我将更新控件。 历史 版本1.0.1 (11/14/2006) 将DialogResult状态转发给调用者。 代码优化。 使用带有特殊标志的SetWindowsPos API来调整控件的大小,而不是直接分配大小来减少闪烁。 控件大小调整现在在WM_SIZING中完成;这修正了在鼠标按钮被释放之前,控件没有为最后一次更新调整大小的错误。 初始版本1.0.0(2006年7月14日) 本文转载于:http://www.diyabc.com/frontweb/news5115.html

  • 相关阅读:
    Recommended Books for Algo Trading in 2020
    Market Making is simpler than you think!
    Top Crypto Market Makers of 2020
    Top Crypto Market Makers, Rated and Reviewed
    爬取伯乐在线文章(五)itemloader
    爬取伯乐在线文章(四)将爬取结果保存到MySQL
    爬取伯乐在线文章(三)爬取所有页面的文章
    爬取伯乐在线文章(二)通过xpath提取源文件中需要的内容
    爬取伯乐在线文章(一)
    爬虫去重策略
  • 原文地址:https://www.cnblogs.com/Dincat/p/13462311.html
Copyright © 2020-2023  润新知