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

I'm doing a Perl/Tk app for a client that has to run (for now) under Win32. I need to do a File..SaveAs and have been looking at some of the UI options available (Tk::FileSelect, etc.). Although my client may see the virtues of platform portability, his customers, being Windows users, need their compfortable look and feel with the least amount of surprise. So it looks like interfacing to COMDLG32.DLL may be my best choice.

Win32::API seems to have all that's necessary to do this, but my attempts at packing the OPENFILENAME data structure to call GetSaveFileName successfully have been futile. Rather than burden the monks with my buggy code, I'm wondering if anyone else has successfully wrestled this wily beast and would be willing to share their experiences.

Thanks.

Replies are listed 'Best First'.
Re: Tk and Common Dialogs
by t0mas (Priest) on Oct 27, 2000 at 11:15 UTC
    Jenda Krynicky has done it in Win32::FileOp which you can download from CPAN. This module is written using Win32::API, so you can look through the code if you want to know how its done.

    I don't like the idea of mixing user interfaces, but if you do, I'm glad to help :)

    /brother t0mas
      It looks like you can find the information you need in Win32::FileOp to do the pack correctly, but it looks like the module hasn't been updated yet to include Win 2000 support. If you're calling the GetSaveFileName in Win 2000, the OPENFILENAME has three additional items you need to pack. They are:
      #if (_WIN32_WINNT >= 0x0500) void * pvReserved; DWORD dwReserved; DWORD FlagsEx; #endif // (_WIN32_WINNT >= 0x0500)
      For more information, see the MSDN page on OPENFILENAME

      Update: I guess it would be nice if I explained the Win 2000 options, instead of making everyone go to the MSDN site.
      Both pvReserved and dwReserved are reserved and should be ignored in the return. FlagsEx can be set to the value OFN_EX_NOPLACESBAR, which means don't display the places bar (whatever that means, I'm still on NT4).

      Guildenstern
      Negaterd character class uber alles!
Re: Tk and Common Dialogs
by $code or die (Deacon) on Oct 27, 2000 at 15:02 UTC
    Oh Joy! - I just remembered I emailed myself the code a while ago and it's stored on an IMAP server - quick login and here it is:

    This defines the mainwindow:
    $top = MainWindow->new(); $top->title("Window Title"); $main_frame = $top->Frame()->pack( -fill=>'both', -expand=>1 );
    Here's the OpenBox Code:
    sub openfile { #print "You clicked Open..\n"; my $opentypes = [ ['CSV Files', '.csv', ], ['TXT Files', '.txt', ], ['All Files', '*', ], ]; $csvfile = $top->getOpenFile(-filetypes=>$opentypes, -title=> "Select + a CSV File"); if ($csvfile ne "") { $csv_entry_box->delete(0,99999); $csv_entry_box->insert(0,$csvfile); ui $main_frame; } }

    Here's the SaveFile Sub

    sub savefile { #print "You clicked Save As..\n"; my $savetypes = [ ['All Files', '*', ], ]; $outfile = $top->getSaveFile(-filetypes=>$savetypes, -title=> "Type a +n output filename"); if ($outfile ne "") { $save_entry_box->delete(0,99999); $save_entry_box->insert(0,$outfile); ui $main_frame; } }

    ui is the sub which has all the unpacked widgets. so ui $main_frame packs all the widgets in ui into $mainframe Then you just need the Tk::MainLoop; call.

    Sorry if this is not very clear, I can email you the full listing if you need it. I found that SpecTcl is a nice little tool to help build the GUI. I am sure I can dig out the URL for it.

    Good Luck
Thank you.
by Anonymous Monk on Oct 28, 2000 at 00:02 UTC
    I downloaded and examined Win32::FileOp. Indeed, it would have taken me awhile to get this data structure packed just right on my own! So I was feeling pretty good about having asked. But then I started to examine $code_or_die's answer, thinking that it was further elaboration on using FileOp. It finally struck me that the getSaveFile he describes is part of Tk! I didn't even know it was there. (It's not mentioned in Learning Perl/Tk. It is referenced in Brent Welch's Practical Programming in Tcl and Tk, albeit without an index entry.) What's more, it has the look and feel that Windows users have come to know (and, for some, love). But it's not implemented as a separate module, there being no .pm file -- just a .pod dated 1996 authored at Sun MicroSystems. And it seems that it must call COMMDLG.DLL, given the nature of the dialog box that pops up.

    So, although I feel somewhat abashed for asking a question that has so obvious an answer, I'm elated at the outcome. It would appear that I can have Windows' look and feel, and portability, too. Thus, two more questions: "Is this little gem available in Linux builds of Perl/Tk, too? Does it then provide a Gnomish or KDEish look and feel, depending on the GUI used?"

    Thanks again to all!
Re: Tk and Common Dialogs
by $code or die (Deacon) on Oct 27, 2000 at 14:47 UTC
    Hello,

    I had a similar project to work on very recently. I had problems to begin with with the GetSaveFileName widgets but it got it working in the end and actually it turned out to be quite simple.

    Unfortunately. I don't have the code with me at the moment - its on my laptop at home. I can post the sub which has the code later.

    $code or die