spikey_wan has asked for the wisdom of the Perl Monks concerning the following question:

Hello World!\n

In this link I talked about positioning the OpenDialog, SaveAsDialog, and BrowseForFolder, dialog boxes with Tk.

Unfortunately, I discovered that you cannot currently affect the positioning of the BrowseForFolder dialog box at all. It will always appear relative to the console window, or in the top left hand corner of the screen if there is no console window, or it's been minimised.

I have been looking into this, and have discovered that a simple mod to C:\Perl\site\lib\Win32\FileOp.pm's BrowseForFolder sub will allow me to pass it a window handle, like you can with the Open and Save dialog boxes.

Change:
sub BrowseForFolder { undef $Win32::FileOp::Error; my ($hwndOwner, $pidlRoot, $pszDisplayName, $lpszTitle, $nFolder, $ulFlags, $lpfn, $lParam, $iImage, $pszPath) = (GetWindowHandle(), "\0"x260, "\0"x260, shift() || "\0", shift() || 0, (shift() || 0) | 0x0000, 0, 0, 0, "\0"x260); $nFolder = CSIDL_DRIVES() unless defined $nFolder; ....
To:
sub BrowseForFolder { undef $Win32::FileOp::Error; my ($pidlRoot, $pszDisplayName, # removed first var $lpszTitle, $nFolder, $ulFlags, $lpfn, $lParam, $iImage, $pszPath, $hwndOwner) # and put it las +t = ("\0"x260, "\0"x260, shift() || "\0", shift() || 0, (shift() || 0) | 0x0000, 0, 0, 0, "\0"x260, shift()); $hwndOwner = GetWindowHandle() unless defined $hwndOwner; #added fo +r if $hwndOwner is undef $nFolder = CSIDL_DRIVES() unless defined $nFolder;

You can then invoke the BrowseForFolder window like this:
my $windowid = hex ($main_window -> id); my $dir = BrowseForFolder("Relative to \$main_window", undef, undef, $ +windowid);
However, if the module is to be changed, then I think it should be done 'properly' by making BrowseForFolder take its arguments in the same way as the other boxes do, and there are a few other mods that I think should be done.

Unfortunately, this and the other suggestions for improvements that I have are completely beyond my meagre perl skills, so I thought it's time to ask for help.

I have emailed Jenda, who is listed as the author in the code, but have had no reply, so I don't know what to do now. Is there someone else out there who's looking after this module, or can anyone submit an update to a module? I don't really know how this part of perl works. I am prepared to do my share of the work, it's just that I don't have all the required skills, yet.

Anyway, here are my suggestions for improving the module, to whoever decides to help me out:

1: It should be possible to pass arguments to BrowseForFolder in exacty the same manner as they can be passed to OpenDialog and SaveAsDialog. i.e.

title => ... filters => ... defaultfilter => ... dir => ... handle => ... options => ... etc...
2: The BrowseForFolder window has "Browse for Folder" in the top bar of the window (where the title should be), and then the title text is displayed in the body of the window below this. This should be modified to be like the other two windows, where the title is displayed in the top bar.

3: It should be possible to specify a directory that BrowseForFolder will open in, rather than just being in the root area. I.e. you could specify something like:

my $windowid = hex ($mw -> id); my $directory = BrowseForFolder ( -title => "Choose Directory:", -CSIDL_opt => 'CSIDL_DRIVES, -BIF_opts => 'BIF_RETURNFSANCESTORS', -open_folder => 'C:\Perl\site\lib\Win32', -handle => $windowid, );
4: It would be great if all the BrowseForFolder, SaveAsDialog and OpenDialog windows had a better method for positioning and sizing rather than just being passed a parent window. It would be great if they could utilize show, or popup, or whatever that would give proper control over their size and positions.

Thanks,
Spike.

Replies are listed 'Best First'.
Re: Need help improving Win32::FileOp
by elwarren (Priest) on Nov 05, 2004 at 20:06 UTC
    The best way to get a response will be to implement your change, test it, and generate a patch for the developer. That way they can integrate it and verify it via the tests you've already provided. Make their work as minimal as possible.