7

我在这里的示例项目工作:http: //www.codeproject.com/Articles/8086/Extending-the-save-file-dialog-class-in-NET

我隐藏了顶部的地址/位置栏并进行了其他修改,但我无法终生禁用让您转到父文件夹的按钮。Ist 在 ToolbarWindow32 类中,这是问题所在。这是我目前所拥有的,但它不起作用:

int parentFolderWindow = GetDlgItem(parent, 0x440);

//Doesn't work
//ShowWindow((IntPtr)parentFolderWindow, SW_HIDE);

//40961 gathered from Spy++ watching messages when clicking on the control
// doesn't work
//SendMessage(parentFolderWindow, TB_ENABLEBUTTON, 40961, 0);

// doesn't work
//SendMessage(parentFolderWindow, TB_SETSTATE, 40961, 0);

//Comes back as '{static}', am I working with the wrong control maybe?
GetClassName((IntPtr)parentFolderWindow, lpClassName, (int)nLength);

或者,如果他们确实使用父文件夹按钮并去我不希望他们去的地方,我可以查看他们所在的新目录,有没有办法可以强制导航返回?

截屏

编辑:添加截图

4

3 回答 3

5

//返回为'{static}',我是否使用了错误的控件?

知道你使用了错误的控件,你期望看到“ToolbarWindow32”回来。一个非常重要的问题,Codeproject.com 代码的一个常见问题,是该代码不能再像发布的那样工作了。自 2004 年以来,Windows 发生了很大的变化。Vista 是从那以后添加一组全新的 shell 对话框的第一个版本,它们基于IFileDialog。与其前身相比有了很大改进,特别是通过IFileDialogCustomize接口自定义对话框更加清晰。实际上不是您想要做的,并且自定义包括修补导航栏。

IFileDialogEvents 接口传递事件,您要查找的是OnFolderChanging事件。旨在阻止用户离开当前文件夹,这是您真正想做的事情。

虽然这在纸上看起来不错,但我应该提醒您不要实际尝试使用这些接口。与 Windows shell 相关的任何东西的一个常见问题是它们只能从 C++ 中轻松使用。COM 接口是“不友好”的类型,基于 IUnknown 的接口没有类型库,您可以使用轻松添加对 C# 或 VB.NET 项目的引用。Microsoft 发布了“Vista 桥”以使这些接口也可以在 C# 中使用,看起来像这样。是的,呸。当您发现必须执行此操作两次时,您会感到很糟糕,这仅适用于更高的 Windows 版本,并且强烈暗示您正在尝试在 XP 上执行此操作(根据您找到的控件 ID 判断)。

这根本不是您想要支持的东西。由于替代方案非常简单,因此请改用受支持的 .NET FileOk 事件。一个 Winform 示例:

    private void SaveButton_Click(object sender, EventArgs e) {
        string requiredDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        using (var dlg = new SaveFileDialog()) {
            dlg.InitialDirectory = requiredDir;
            dlg.FileOk += (s, cea) => {
                string selectedDir = System.IO.Path.GetDirectoryName(dlg.FileName);
                if (string.Compare(requiredDir, selectedDir, StringComparison.OrdinalIgnoreCase) != 0) {
                    string msg = string.Format("Sorry, you cannot save to this directory.\r\nPlease select '{0}' instead", requiredDir);
                    MessageBox.Show(msg, "Invalid folder selection");
                    cea.Cancel = true;
                }
            };
            if (dlg.ShowDialog() == DialogResult.OK) {
                // etc...
            }
        }
    }
于 2014-04-30T11:37:45.670 回答
1

我不认为这会奏效。即使您禁用该按钮,他们也可以键入..\并单击“保存”,这会将它们提升一级。您不能完全禁用文件名文本框并保持对话框的功能。

您最好使用FolderBrowserDialog并设置它的 RootFolder 属性并要求用户输入文件名或自动生成它。

如果您想要限制用户的文件夹不是Environment.SpecialFolder那么您需要做一些工作来调用SHBrowseForFolderManually usingILCreateFromPath以获得一个 PIDLIST_ABSOLUTE 为您的路径传递给 BROWSEINFO.pidlRoot

你可以反思FolderBrowserDialog.RunDialog一下,看看如何打这个电话。

于 2014-04-30T10:36:52.427 回答
1

由于您想要这样的自定义行为而不是开发低级代码(这可能会在下一版本的 Windows 中中断),您可以尝试开发您的文件选择器表单。

基本上它是一个简单的树视图 + 列表视图。微软有一个演练

这将花费您半天的时间,但是一旦您有了自定义表单,您就可以定义您需要的所有行为,而无需任何技巧和限制。

于 2014-05-07T08:15:20.700 回答