c# customizing controls on a save dialog -- how to disable parent folder button?
Asked Answered
C

3

7

I am working from the sample project here: http://www.codeproject.com/Articles/8086/Extending-the-save-file-dialog-class-in-NET

I have hidden the address/location bar at the top and made other modifications but I can't for the life of me manage to disable the button that lets you go up to the parent folder. Ist is in the ToolbarWindow32 class which is the problem. This is what I have at the moment but it is not working:

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);

Alternatively, if they do use the parent folder button and go where I don't want them to, I'm able to look at the new directory they land in, is there a way I can force the navigation to go back?

Screenshot

Edit: Added screenshot

Caecum answered 28/4, 2014 at 7:19 Comment(1)
Have you tried looking at this articleThermostatics
D
5

//Comes back as '{static}', am I working with the wrong control maybe?

You know you are using the wrong control, you expected to see "ToolbarWindow32" back. A very significant problem, a common one for Codeproject.com code, is that this code cannot work anymore as posted. Windows has changed too much since 2004. Vista was the first version since then that added a completely new set of shell dialogs, they are based on IFileDialog. Much improved over its predecessor, in particular customizing the dialog is a lot cleaner through the IFileDialogCustomize interface. Not actually what you want to do, and customizations do not include tinkering with the navigation bar.

The IFileDialogEvents interface delivers events, the one you are looking for is the OnFolderChanging event. Designed to stop the user from navigating away from the current folder, the thing you really want to do.

While this looks good on paper, I should caution you about actually trying to use these interfaces. A common problem with anything related to the Windows shell is that they only made it easy to use from C++. The COM interfaces are the "unfriendly" kind, interfaces based on IUnknown without a type library you can use the easily add a reference to your C# or VB.NET project. Microsoft published the "Vista bridge" to make these interfaces usable from C# as well, it looks like this. Yes, yuck. Double yuck when you discover you have to do this twice, this only works on later Windows versions and there's a strong hint that you are trying to do this on XP (judging from the control ID you found).

This is simply not something you want to have to support. Since the alternative is so simple, use the supported .NET FileOk event instead. A Winforms example:

    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...
            }
        }
    }
Degas answered 30/4, 2014 at 11:37 Comment(1)
Thanks for that extra info Hans but I am already using the FileOK check afterward to make sure they saved in the right folder or it's children. I also have already done most of the work using that demo project (Removed address bar and did my own OnFolderChange check so that if it's above that folder I've set up it displays the window above). So I was hoping to keep that and just do this final changeCaecum
D
1

I don't this is going to work. Even if you disable the button they can type ..\ and click save and it will take them up one level. You can't exactly disable the file name text box and maintain the functionality of the dialog.

You'd be better off either using the FolderBrowserDialog and setting it's RootFolder property and asking the user to type the filename in or auto generating it.

If the folder you are wanting to restrict the users to isn't an Environment.SpecialFolder Then you'll need to do some work to make the call to SHBrowseForFolder Manually using ILCreateFromPath to get a PIDLIST_ABSOLUTE for your path to pass to the BROWSEINFO.pidlRoot

You can reflect FolderBrowserDialog.RunDialog to see how to make that call.

Danczyk answered 30/4, 2014 at 10:36 Comment(1)
Security isn't an issue, so anyone using "..\" will not get confused using this. I can't use a FolderBrowserDialog because this is meant for saving files to cloud storage services like google drive, I need to show them the files they already have on there so they don't overwrite anything accidentally. I'm afraid if they get a few folders deep in their google drive folders and start mashing the folder up button they will overshoot into the temp folder area.Caecum
V
1

Since you want such custom behaviors instead of developing low level code (that is likely yo break in the next versions of windows) you can try to develop your file picker form.

Basically it is a simple treeview + list view. Microsoft has a walk-through .

It will take you half a day but once you have your custom form you can define all behaviors you need without tricks and limits.

Versicolor answered 7/5, 2014 at 8:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.