From: <mie...@us...> - 2013-02-02 01:43:25
|
Revision: 8920 http://sourceforge.net/p/oorexx/code-0/8920 Author: miesfeld Date: 2013-02-02 01:43:22 +0000 (Sat, 02 Feb 2013) Log Message: ----------- Feature Requests: #520 folder selection dialog See ticket [Feature-requests:#520] Modified Paths: -------------- ooDialog/trunk/examples/examples/browsePrinters.rex Modified: ooDialog/trunk/examples/examples/browsePrinters.rex =================================================================== --- ooDialog/trunk/examples/examples/browsePrinters.rex 2013-02-02 01:41:19 UTC (rev 8919) +++ ooDialog/trunk/examples/examples/browsePrinters.rex 2013-02-02 01:43:22 UTC (rev 8920) @@ -36,20 +36,22 @@ /*----------------------------------------------------------------------------*/ /** - * A quick example of the SimpleFolderBrowse class. This class only has one - * method: getFolder() and it is a class method. + * An example showing usage of the BrowseForFolder class. This example shows + * how to use the class to browse virtual folders, in this case the Printers + * folder. * - * It is very easy to use, you just invoke the getFolder() method and the folder - * picked by the user is returned. When the user picks a folder the fully - * qualified path name is returned. If the user cancels, the empty string is - * returned. + * The BrowseForFolder object puts up the same Windows Shell browse dialog as + * does the SimpleFolderBrowse object, but it is much more configurable. * - * It is possible, depending on how the dialog is set up, for the user to pick a - * virtual folder that has no file system path. In that case, .nil is returned. + * This example uses the browse for folder dialog to let the user select a + * printer. * + * The example puts up a regular dialog and on the push of a button shows the + * browse for folder dialog set to browse only printers. The user's pick is + * is displayed in an edit box. */ - -- Set up some symbolic IDs and then put up our dialog. + -- Set up some symbolic IDs and then put up our example dialog. .application~setDefaults('O', , .false) .constDir[IDC_PB_BROWSE] = 100 .constDir[IDC_ST_RESULTS] = 101 @@ -66,11 +68,29 @@ ::class 'PrintersDialog' subclass UserDialog +/** init() + * + * Typical UserDialog init() method. Initializes the super class, the starts + * the dialog template by creating the frame in the template. Internally, the + * create() method will invoke the define() method. When create() returns, + * the dialog template will be complete. + */ ::method init forward class (super) continue self~create(30, 30, 257, 123, "Browse For Printers Example", "CENTER") + +/** define() + * + * A typical define() method for a UserDialog. We create a push button in the + * dialog template that allows the user to show the browse for folder dialog. + * + * An edit control and two radio buttons are created, the edit control shows + * the result of the user's selection in the browse for folder dialog. The + * radio button control how the selection is returned from the browse for + * folder dialog. + */ ::method defineDialog self~createStaticText(IDC_ST_RESULTS, 10, 10, 30, 11, , "Results:") @@ -85,26 +105,78 @@ * * The event handler for the Browse Printers push button. We configure a * BrowseForFolder object, display it, and report the user's actions in the edit - * control + * control. + * + * The Windows Shell keeps track of things in the shell using a structure called + * an 'item ID list.' Every thing in the shell has an item ID list. Most + * things in the shell have a corresponding file system path. But not every + * thing. Virtual folders like the printer objects do not have a file system + * path. + * + * The getFolder() method returns the file system path picked by the user. That + * method can not return a value for a virtual folder, so it returns .nil. To + * get the printer the user picks, we need to use the getItemIDList() method. + * This method returns the handle to an item ID list. + * + * Currently, the programmer can not do much with an item ID list handle. This + * may change in future versions of ooDialog. However, the programmer can get + * the display name of the shell item through the item ID list, which is what + * we do here. + * + * Like most, if not all, handles in Windows, the item ID list handle represents + * a system resource that has been allocated by the OS. When the Rexx + * programmer is done with the item ID list, it is good practice to release the + * handle to free up the system resources used by the item ID list. */ ::method onBrowse unguarded - expose rbShort edit + expose rbShort edit + -- Set title, banner, and a hint for the dialog. title = 'Browse For a Printer' banner = 'Select the printer to use for this test.' hint = 'This is only a demonstration, no printing will be done.' bff = .BrowseForFolder~new(title, banner, hint) + + -- Make this dialog the owner window of the browse dialog. The root for the + -- browse dialog will be the virtual Printers folder. If that is not set, + -- the user will not see the printers. In addition, we want the user to + -- only see the printers. That way, if the dialog is not canceled, we are + -- sure a printer was picked and not some random folder. bff~owner = self bff~root = 'CSIDL_PRINTERS' + + -- Set non-default options for the browse dialog. We need the browse for + -- printers option. The operating system will not allow a new folder to be + -- created in the virtual printers folder, so it disables the Make New + -- Folder button. It looks better to just remove the button altogether. bff~options = 'BROWSEFORPRINTERS NONEWFOLDERBUTTON' + -- The getItemIDList() method is what actually puts up the browse for folder + -- dialog. Normally, by default, the getItemIDList() will release the COM + -- resources used our BrowseForFolder object. But, we still need the COM + -- resources to be able to use the getDisplayName() method. So, we tell the + -- method we still need COM active by passing in .true to the method. + -- + -- We we tell the object we still need COM, it then becomes our + -- responsibility to release COM. If the user cancels, we release COM and + -- return. Otherwise, we release COM further down in this method when we + -- are finished with COM. pidl = bff~getItemIDList(.true) if pidl == .nil then do edit~setText('The user canceled.') + bff~releaseCOM return 0 end + -- Decide what the format for the returned display name. With no arguments, + -- the getDisplayName() method will try to return the most complete name. + -- For a folder with a file system path, that will be a fully qualified + -- path name. For a virtual folder, the name will include the parent + -- folder(s) of the actual folder picked. + -- + -- The second optional argument to getDisplayName() specifies the format of + -- the returned name. Normal display will be just the printer name. if rbShort~checked then do name = bff~getDisplayName(pidl, 'NORMALDISPLAY') end @@ -115,6 +187,11 @@ -- We are done with pidl, release it. bff~releaseItemIDList(pidl) + -- We are done with the BrowseForFolder object. Since we told the + -- getItemIDList() method to not release the COM resources, we need to + -- explicitly do it ourself. + bff~releaseCOM + -- Determine text for the edit control ... if name == .nil then do text = 'Unexpected result. ' .DlgUtil~errMsg(.systemErrorCode) |