PROCEDURE SelectMultipleImages
PARAMETERS laFiles
DO declare
#DEFINE OPENFILENAME_SIZE 76 && set to 88 for W2K
LOCAL lcBuffer, loFilter, loTitlebar, loFilename, loFilenameRet,;
loDefExt, loStartDir, lnErrorCode
* dialog title
loTitlebar = CreateObject("PChar", "Open a database file")
* file types filter
loFilter = CreateObject("PChar",;
"Image Files (*.bmp;*.jpg;*.jpeg;*.gif)" + Chr(0) + ;
"*.bmp;*.jpg;*.jpeg;*.gif")
* default extension, in case if user type a name with no extension
loDefExt = CreateObject("PChar", "DBC")
* suggest a file name or put just an empty string
loFilename = CreateObject("PChar", Padr("test.dbc", 250,Chr(0)))
* a space for file name to be returned
loFilenameRet = CreateObject("PChar", Repli(Chr(0),250))
* initial directory displayed in the dialog
loStartDir = CreateObject("PChar", SYS(5)+SYS(2003))
* configuration flags
#DEFINE OFN_HIDEREADONLY 0x4
#DEFINE OFN_NOCHANGEDIR 0x8
#DEFINE OFN_PATHMUSTEXIST 0x800
#DEFINE OFN_FILEMUSTEXIST 0x1000
#DEFINE OFN_ALLOWMULTISELECT 0x200
#DEFINE OFN_EXPLORER 0x80000
#DEFINE OFN_DONTADDTORECENT 0x2000000
lnFlags = OFN_PATHMUSTEXIST + OFN_FILEMUSTEXIST + ;
OFN_HIDEREADONLY + OFN_NOCHANGEDIR + ;
OFN_ALLOWMULTISELECT + OFN_EXPLORER
* assembling the OPENFILENAME structure
lcBuffer = num2dword(OPENFILENAME_SIZE) +;
num2dword(GetActiveWindow()) +;
num2dword(0) +;
num2dword(loFilter.GetAddr()) +;
num2dword(0) + num2dword(0) + num2dword(1) +;
num2dword(loFilename.GetAddr()) +;
num2dword(loFilename.GetAllocSize()) +;
num2dword(loFilenameRet.GetAddr()) +;
num2dword(loFilenameRet.GetAllocSize()) +;
num2dword(loStartDir.GetAddr()) +;
num2dword(loTitlebar.GetAddr()) +;
num2dword(lnFlags) +;
num2dword(0) +;
num2dword(loDefExt.GetAddr()) +;
num2dword(0) + num2dword(0) + num2dword(0)
* creating an Open dialog box
IF GetOpenFileName(@lcBuffer) = 0
lnErrorCode = CommDlgExtendedError()
IF lnErrorCode <> 0
? "Error code:", lnErrorCode
ELSE
* the Cancel button selected
ENDIF
RETURN null
ELSE
* Read the null-separated string data from the buffer
lcSelectedData = loFilename.GetValue()
* Trim trailing nulls
lcSelectedData = LEFT(lcSelectedData, AT(CHR(0)+CHR(0), lcSelectedData) - 1)
* Replace nulls with delimiter for parsing
lcSelectedData = STRTRAN(lcSelectedData, CHR(0), "|")
* Split into array
DIMENSION laFiles[GETWORDCOUNT(lcSelectedData,"|")]
FOR i = 1 TO ALEN(laFiles)
laFiles[i] = GETWORDNUM(lcSelectedData,i,"|")
ENDFOR
* If multiple files: first entry is directory, rest are filenames
IF ALEN(laFiles) > 1
lcPath = ADDBS(laFiles[1])
FOR i = 2 TO ALEN(laFiles)
laFiles[i-1] = lcPath + laFiles[i]
&& overwrite with full path
ENDFOR
DIMENSION laFiles[ALEN(laFiles)-1] && shrink array to remove folder entry
ENDIF
* RETURN @laFiles
* Display results
*FOR i = 1 TO ALEN(laFiles)
* ? "Selected File " + TRANSFORM(i) + ": " + laFiles[i]
*ENDFOR
ENDIF
* end of main
PROCEDURE declare
DECLARE INTEGER GetOpenFileName IN comdlg32 STRING @lpofn
DECLARE INTEGER GetActiveWindow IN user32
DECLARE INTEGER GlobalFree IN kernel32 INTEGER hMem
DECLARE INTEGER CommDlgExtendedError IN comdlg32
DEFINE CLASS PChar As Custom
hMem=0
PROCEDURE Init (lcString)
THIS.SetValue (lcString)
PROCEDURE Destroy
THIS.ReleaseString
FUNCTION GetAddr && returns a pointer to the string
RETURN THIS.hMem
FUNCTION GetValue && returns string value
LOCAL lnSize, lcBuffer
lnSize = THIS.getAllocSize()
lcBuffer = SPACE(lnSize)
IF THIS.hMem <> 0
DECLARE RtlMoveMemory IN kernel32 As Heap2Str;
STRING @, INTEGER, INTEGER
= Heap2Str (@lcBuffer, THIS.hMem, lnSize)
ENDIF
RETURN lcBuffer
FUNCTION GetAllocSize && returns allocated memory size (string length)
DECLARE INTEGER GlobalSize IN kernel32 INTEGER hMem
RETURN Iif(THIS.hMem=0, 0, GlobalSize(THIS.hMem))
PROCEDURE SetValue(lcString) && assigns new string value
#DEFINE GMEM_FIXED 0
THIS.ReleaseString
DECLARE INTEGER GlobalAlloc IN kernel32 INTEGER, INTEGER
DECLARE RtlMoveMemory IN kernel32 As Str2Heap;
INTEGER, STRING @, INTEGER
LOCAL lnSize
lcString = lcString + Chr(0)
lnSize = Len(lcString)
THIS.hMem = GlobalAlloc (GMEM_FIXED, lnSize)
IF THIS.hMem <> 0
= Str2Heap (THIS.hMem, @lcString, lnSize)
ENDIF
PROCEDURE ReleaseString && releases allocated memory
IF THIS.hMem <> 0
DECLARE INTEGER GlobalFree IN kernel32 INTEGER
= GlobalFree (THIS.hMem)
THIS.hMem = 0
ENDIF
ENDDEFINE
FUNCTION buf2word(lcBuffer)
RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ;
Asc(SUBSTR(lcBuffer, 2,1)) * 256
FUNCTION num2dword(lnValue)
#DEFINE m0 256
#DEFINE m1 65536
#DEFINE m2 16777216
IF lnValue < 0
lnValue = 0x100000000 + lnValue
ENDIF
LOCAL b0, b1, b2, b3
b3 = Int(lnValue/m2)
b2 = Int((lnValue - b3*m2)/m1)
b1 = Int((lnValue - b3*m2 - b2*m1)/m0)
b0 = Mod(lnValue, m0)
RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)
