[PythonCE] Open File dialog example
Telion
telionce@yahoo.com
Mon, 7 Oct 2002 19:19:02 -0700 (PDT)
I've followed the example of Jeff, and written a small class
that enables easy interface with external C functions.
(especially for win32apis that require struct)
I made this because I wanted to use GetOpenFileName()
included in win32gui.
_test() shows how to use this class and the common
file dialog function.
Please improve it, and let me know.
Telion
------------------------------
#
# This class creates "struct" for external C functions
# It takes list or tuple of (name, format_string, initial_value) for
# each struct member.
# If the struct has padding byte(s), you have to provide dummy member for it.
#
# See the _test() for example
#
# 02/10/07 22:08
# Telion
#
import struct
class cStruct(object):
def __init__(self, sd):
#print "cStruct"
self.sd=list(sd)
self.nlst = [i[0] for i in sd]
self.fs = "".join([i[1] for i in sd])
t = [i[2] for i in sd]
self.data = struct.pack(self.fs, *t)
self.ptr = str2ptr(self.data)
def __setattr__(self, name, v):
if name in ['sd', 'nlst', 'fs', 'data', 'ptr']:
object.__setattr__(self, name, v)
return
t = list(struct.unpack(self.fs, self.data))
i = self.nlst.index(name)
if i > -1:
t[i] = v
self.data = struct.pack(self.fs, *t)
def __getattr__(self, name):
t = struct.unpack(self.fs, self.data)
i = self.nlst.index(name)
if i > -1:
return t[i]
else:
raise AttributeError
def __str__(self):
return self.data
def dump(self): # use this to see the data
t = struct.unpack(self.fs, self.data)
ii = 0
for i in self.nlst:
print i, "=", t[ii]
ii += 1
print "fs = ", self.fs
print "ptr = ", self.ptr
return
#
# a few helper functions
#
# try to get the pointer for the string data
def str2ptr(s):
try:
import calldll # use calldll...if you have
try:
return calldll.strptr(s) # not all calldll has strptr
except:
pass
except:
pass
return id(s)+20 # This can be different...Check!
# make NULL terminated C unicode string ( without BOM )
def stru16(s):
return unicode(s).encode('utf-16')[2:]+"\0\0"
# returns 'mbcs' Python string from C unicode string (NULL terminated, wittout
BOM)
def u16str(u):
ss = u[:u.index('\0\0')+1] # Get up to double null byte.
if len(ss) < 2:
return ""
return unicode(''.encode('utf-16')+ss, 'utf-16').encode('mbcs') # Add BOM
def _test(title="", inidir=""):
# cStruct class uses following struct information.
# (name, fs, initial_value)
#
# "name" is used for accessing value
# "fs" is format string for that value (see struct module doc)
# For lpstr, lpcstr, lpxxx, use 'l'.
# "initial_value" default value
#
# In this test, we create OPNEFILENAME struct for GetOpenFineName().
# And retrieve filenname specified by user.
#
# File dialog access is easy.
#
# >>> import cs
# >>> fn = cs._test()
# >>> print fn
# >>> fn = cs._test(r'DialogTitle',r'\storage card')
#
import sys
tt = ( \
('lStructSize', 'l', 76 ) , # always 76 for CE?
('hwndOwner', 'l', sys.stdout.hwnd ) , # shell.hwnd
('hInstance', 'l', sys.hinst) ,
('lpstrFilter', 'l', 0 ), # File type filter
('lpstrCustomFilter', 'l', 0 ),
('nMaxCustFilter', 'l', 0 ) , # Not supported in CE
('nFilterIndex', 'l', 0 ) , #
('lpstrFile', 'l', 0 ) , # Initial File name and file name buffer.
('nMaxFile', 'l', 256 ) , # BufferSize of file name string 256 or more
('lpstrFileTitle', 'l', 0 ) , # (optional) base name recievinbg buffer
('nMaxFileTitle', 'l', 0 ) , # max size of above
('lpstrInitialDir', 'l', 0 ) , # (optional) initial directory
('lpstrTitle', 'l', 0 ) , # TitileBar of Dialog
('Flags', 'l', 0 ) , #
('nFileOffset', 'H', 0 ) , # offset to basa name ) , #) , #) , # WORD
('nFileExtension', 'H', 0 ) , # offset to extension ) , #) , #) , # WORD
('lpstrDefExt', 'l', 0 ) , # default extension
('lCustData', 'l', 0 ) , # Not supported in CE
('lpfnHook', 'l', 0 ) , # Not supported in CE
('lpTemplateName', 'l', 0 ) # Not supported in CE
)
#print tt
cs1 = cStruct(tt)
filename = "\0"*580 # initialize filename buffer with NULL
cs1.lpstrFile = str2ptr(filename)
if not title:
title = r'Choose a file' # Set a string for testing
dialogtitle = stru16(title)
cs1.lpstrTitle = str2ptr(dialogtitle)
if not inidir:
inidir = r'\Program Files' # Set initial directory for testing
inidir = stru16(inidir)
cs1.lpstrInitialDir = str2ptr(inidir) # str2ptr is not good enough
import win32gui
win32gui.GetOpenFileName(cs1.data)
ss = u16str(filename)
return ss # return the filename
# debug code
print ss # This works ascii file name only. mbcs filename needs more effort?
print "="*10
cs1.dump() # dump information about struct
return ss # return the filename
=====
Telion
- telionce@yahoo.com -
http://pages.ccapcable.com/lac/PythonCE.html
__________________________________________________
Do you Yahoo!?
Faith Hill - Exclusive Performances, Videos & More
http://faith.yahoo.com