c#自定义保存对话框上的控件 - 如何禁用父文件夹按钮?

Bry*_*yan 7 c# windows-messages savefiledialog ofnhookproc

我在这里的示例项目工作: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);
Run Code Online (Sandbox Code Playgroud)

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

截图

编辑:添加截图

Han*_*ant 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...
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)


Jam*_*ass 1

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

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

如果您想要限制用户的文件夹不是 那么Environment.SpecialFolder您需要做一些工作来调用SHBrowseForFolder手动使用ILCreateFromPath来获取 PIDLIST_ABSOLUTE 以便您的路径传递到 BROWSEINFO.pidlRoot

您可以反思FolderBrowserDialog.RunDialog一下如何拨打该电话。