Win32gui... file dialogs?
Kevin Cazabon
kcazabon at home.com
Mon Aug 28 00:56:26 EDT 2000
Hey Alex;
Can the forSave flag be set to some other value for selecting a directory
instead of a file? I can't seem to find any documentation on Mark's
win32gui module to find out what the function would be...
| if forSave == 0: isok=win32gui.GetSaveFileName(ofn)
| elif forSave == 1: isok=win32gui.GetOpenFileName(ofn)
| elif forSave == 2: isok = win32gui.GetOpenDirName(ofn) # or
whatever...
The version of Win32 that I'm running doesn't have GetSaveFileName in it
yet... I'm still using build 128. I am going to upgrade to the last 1.5.2
version, but have some rework to do before I can migrate to 1.6 (I'm waiting
for a final release first too).
What's the function name for select directory, if there is one, in the
current win32gui?
Thanks,
Kevin.
"Alex Martelli" <alex at magenta.com> wrote in message
news:8ob6b3112il at news2.newsguy.com...
| "Kevin Cazabon" <kcazabon at home.com> wrote in message
| news:l1Zp5.210819$8u4.2129533 at news1.rdc1.bc.home.com...
| [snip]
| > -how would you set initial directory and file?
| > -how would you set filters (multiple types, or a single selected type
with
| > multiple extensions)
|
| The current version (see later) lets you do all of these (and a bit more).
| Still a small fraction of the common-file-dialog's actual flexibility, but
| more of it can be added if need be.
|
| > It'd be nice if we could come up with a dummy-proof Python script that
| > allowed you to interface with the dialog through standard Python args...
| > I'm sure there's more than one person out there that would appreciate it
| as
| > much as I...
|
| No doubt, which is why I've proceeded with the development.
|
| > Can I convince you to help me one step further? q:]
|
| Sure, here comes the newest version of ofn.py...:
|
|
| import win32gui, struct, array, string
| """ofn.py: Win32 functions to get 1 or more filenames for Open or Save,
| via user interaction with the file-select Common Dialog.
| """
| # A. Martelli, 2000-08-27; placed in the public domain.
|
| OFN_ALLOWMULTISELECT=0x00000200
| OFN_EXPLORER=0x00080000
|
| def arrayToStrings(resultArray):
| """return list-of-strings corresponding to a char array,
| where each string is terminated by \000, and the whole
| list by two adjacent \000 bytes
| """
| astr=resultArray.tostring()
| manyStrings=[]
| # perhaps a loop of string.split would be faster...
| while len(astr) and astr[0]!='\000':
| i=astr.index('\000')
| manyStrings.append(astr[:i])
| astr=astr[i+1:]
| return manyStrings
|
| def szFrom(anarray):
| """return the string-pointer (sz) corresponding to a char
| array, 0 (null pointer) if no array
| """
| if anarray: return anarray.buffer_info()[0]
| else: return 0
|
| def arrayFrom(astring,additional=0):
| """return a char array built from a string, plus 0
| or more \000 bytes as filler
| """
| if not astring: astring=''
| return array.array('c',astring+additional*'\000')
|
| def arrayMulti(stringlist):
| """return a char array built from many strings, each
| separated by a \000 byte, and two \000's at the end
| """
| return arrayFrom(string.join(stringlist,'\000'),2)
|
| def buildOfn(resultarray,filters=None,initdir=None,title=None,
| multisel=1,oldlook=0):
| """build an OPENFILENAME struct as a string, with several
| options and a given result-array for the string[s] that
| will result from the GetOpenFileName call
| """
| flags=OFN_EXPLORER
| if multisel: flags=flags|OFN_ALLOWMULTISELECT
| if oldlook: flags=flags&~OFN_EXPLORER
| szfile,maxfile=resultarray.buffer_info()
| szfilter=szFrom(filters)
| szinitdir=szFrom(initdir)
| sztitle=szFrom(title)
| return struct.pack(
| "3i2P2iPiPi2PI2hPi2P",
| 76, 0, 0, # size, owner-hwnd, hinstance
| szfilter, 0, 0, 0, # filter, custom-filter, max-cust-filter,
| filter-index
| szfile, maxfile, # file, max-file
| 0, 0, # file-title, max-file-title
| szinitdir, sztitle, # initial-dir, dialog-title
| flags, 0, 0, # flags, file-offset, file-extension
| 0, # def-ext
| 0, 0, 0) # cust-data, func-hook, template-name
|
| def openNames(forsave=0,filters=None,initdir=None,title=None,
| initfile=None,multisel=1,oldlook=0):
| """return a list of filenames for open or save, given
| interactively by the user through a common-dialog; if
| more than 1 string is returned, the first is the directory,
| followed by the filenames.
| """
| resultBuffer=arrayFrom(initfile,8192)
| title=arrayFrom(title)
| initdir=arrayFrom(initdir)
| filters=arrayMulti(filters)
| ofn=buildOfn(resultBuffer,filters,initdir,title,multisel,oldlook)
| if forSave: isok=win32gui.GetSaveFileName(ofn)
| else: isok=win32gui.GetOpenFileName(ofn)
| if not isok: return []
| return arrayToStrings(resultBuffer)
|
| def _test():
| return openNames(
| filters=('Texts and scripts','*.txt;*.py','Py stuff','*.py*')
| )
|
| if __name__=='__main__':
| print _test()
|
|
| This ofn.openNames() offers only a subset of the flexibility of the
| underlying GetOpenFileName/GetSaveFileName calls, but I've
| tried to make it a reasonable subset! The filters argument is
| a list of strings, alternatively the string that's displayed for that
| filter in the dialog's combobox, and the corresponding mask
| (one or more wildcard-containing expressions separated by
| semicolons). initdir, title (dialog's title) and initfile, if present,
| are each just a Python string. forsave, multisel and oldlook are
| just boolean values (multisel defaults to true, the others to
| false). The return value is a list of:
| - 0 strings, if the user has clicked Cancel on the dialog,
| - 1 string, the full pathname, if 1 file was selected and OK'd
| - n+1 strings, if n files were selected and OK'd: first the
| directory in which the files reside, then the n files themselves
| (for each, just the filename.ext; path is not repeated).
|
| Anything important still missing...?
|
| Testing has been spotty -- let me know of any problems and I'll
| try to reproduce and solve them.
|
|
| Alex
|
|
|
|
More information about the Python-list
mailing list