diff --git a/FileName_Caps/CONFIG/config.fpw b/FileName_Caps/CONFIG/config.fpw
new file mode 100644
index 0000000..ef3f93b
--- /dev/null
+++ b/FileName_Caps/CONFIG/config.fpw
@@ -0,0 +1,2 @@
+SCREEN=OFF
+RESOURCE=OFF
\ No newline at end of file
diff --git a/FileName_Caps/Filename_caps.pj2 b/FileName_Caps/Filename_caps.pj2
new file mode 100644
index 0000000..24e849d
--- /dev/null
+++ b/FileName_Caps/Filename_caps.pj2
@@ -0,0 +1,87 @@
+*--------------------------------------------------------------------------------------------------------------------------------------------------------
+* (ES) AUTOGENERADO - ¡¡ATENCIÓN!! - ¡¡NO PENSADO PARA EJECUTAR!! USAR SOLAMENTE PARA INTEGRAR CAMBIOS Y ALMACENAR CON HERRAMIENTAS SCM!!
+* (EN) AUTOGENERATED - ATTENTION!! - NOT INTENDED FOR EXECUTION!! USE ONLY FOR MERGING CHANGES AND STORING WITH SCM TOOLS!!
+*--------------------------------------------------------------------------------------------------------------------------------------------------------
+*< FOXBIN2PRG: Version="1.19" SourceFile="filename_caps.pjx" /> (Solo para binarios VFP 9 / Only for VFP 9 binaries)
+*
+LPARAMETERS tcDir
+
+lcCurdir = SYS(5)+CURDIR()
+CD ( EVL( tcDir, JUSTPATH( SYS(16) ) ) )
+
+*
+_Author = ""
+_Company = ""
+_Address = ""
+_City = ""
+_State = ""
+_PostalCode = ""
+_Country = ""
+*--
+_Comments = "Capitalization for files"
+_CompanyName = "Fernando D. Bozzo"
+_FileDescription = "Capitalization for files"
+_LegalCopyright = "Creative Commons 4: Reconocimiento - CompartirIgual (by-sa): http://creativecommons.org/licenses/by/4.0/"
+_LegalTrademark = "Creative Commons 4: Reconocimiento - CompartirIgual (by-sa): http://creativecommons.org/licenses/by/4.0/"
+_ProductName = "FILENAME_CAPS"
+_MajorVer = "2"
+_MinorVer = "3"
+_Revision = "0"
+_LanguageID = ""
+_AutoIncrement = "0"
+*
+
+
+*
+*<.HomeDir = 'c:\desa\filename_caps' />
+
+FOR EACH loProject IN _VFP.Projects FOXOBJECT
+ loProject.Close()
+ENDFOR
+
+STRTOFILE( '', '__newproject.f2b' )
+BUILD PROJECT Filename_caps.pjx FROM '__newproject.f2b'
+FOR EACH loProject IN _VFP.Projects FOXOBJECT
+ loProject.Close()
+ENDFOR
+
+MODIFY PROJECT 'Filename_caps.pjx' NOWAIT NOSHOW NOPROJECTHOOK
+
+loProject = _VFP.Projects('Filename_caps.pjx')
+
+WITH loProject.FILES
+ .ADD('config\config.fpw') && *< FileMetadata: Type="T" Cpid="1252" Timestamp="0" ID="0" ObjRev="0" />
+ .ADD('filename_caps.prg') && *< FileMetadata: Type="P" Cpid="1252" Timestamp="0" ID="0" ObjRev="544" />
+ *
+
+ .ITEM('__newproject.f2b').Remove()
+
+ *
+ *
+
+ *
+ *
+
+ *
+ .ITEM(lcCurdir + 'config\config.fpw').Type = 'T'
+ *
+ENDWITH
+
+WITH loProject
+ *
+ .SetMain(lcCurdir + 'filename_caps.prg')
+ .Debug = .T.
+ .Encrypted = .F.
+ *<.CmntStyle = 1 />
+ *<.NoLogo = .F. />
+ *<.SaveCode = .T. />
+ .ProjectHookLibrary = ''
+ .ProjectHookClass = ''
+ *
+ENDWITH
+
+
+_VFP.Projects('Filename_caps.pjx').Close()
+*ERASE '__newproject.f2b'
+CD (lcCurdir)
+RETURN
\ No newline at end of file
diff --git a/FileName_Caps/Filename_caps.pjt b/FileName_Caps/Filename_caps.pjt
new file mode 100644
index 0000000..7061166
Binary files /dev/null and b/FileName_Caps/Filename_caps.pjt differ
diff --git a/FileName_Caps/Filename_caps.pjx b/FileName_Caps/Filename_caps.pjx
new file mode 100644
index 0000000..96f0b1a
Binary files /dev/null and b/FileName_Caps/Filename_caps.pjx differ
diff --git a/FileName_Caps/Normalize_FileNames.vbs b/FileName_Caps/Normalize_FileNames.vbs
new file mode 100644
index 0000000..e06849f
--- /dev/null
+++ b/FileName_Caps/Normalize_FileNames.vbs
@@ -0,0 +1,96 @@
+'---------------------------------------------------------------------------------------------------
+' Normalize_FileNames.vbs - 06/01/2014 - Fernando D. Bozzo (fdbozzo@gmail.com)
+'---------------------------------------------------------------------------------------------------
+' ENGLISH:
+' Create a shortcut on user's "SendTo" folder and configure CAPS on filename_caps.cfg
+'
+' ESPAÑOL:
+' Cree un acceso directo en la carpeta "SendTo" del usuario y configure las Capitalizaciones en filename_caps.cfg
+'---------------------------------------------------------------------------------------------------
+Const ForReading = 1
+Dim WSHShell, FileSystemObject
+Dim oVFP9, nExitCode, cEXETool, cCMD, nDebug, cConvertType, aExtensions(8), filename_caps_log
+Dim i, x, str_cfg, aConf
+Set WSHShell = WScript.CreateObject("WScript.Shell")
+Set FileSystemObject = WScript.CreateObject("Scripting.FileSystemObject")
+Set oVFP9 = CreateObject("VisualFoxPro.Application.9")
+filename_caps_log = Replace(WScript.ScriptFullName, WScript.ScriptName, "filename_caps.log")
+nExitCode = 0
+'---------------------------------------------------------------------------------------------------
+nDebug = 5 'Cumulative Flags: 0=OFF, 1=Create filename_caps LOG, 2=Only show script calls, 4=Don't show filename_caps error modal messages
+'---------------------------------------------------------------------------------------------------
+
+If WScript.Arguments.Count = 0 Then
+ nExitCode = 1
+ cErrMsg = "nDebug = " & nDebug
+ If GetBit(nDebug, 1) Then
+ cErrMsg = cErrMsg & Chr(13) & "Bit 0 ON: (1) Create filename_caps LOG"
+ End If
+ If GetBit(nDebug, 2) Then
+ cErrMsg = cErrMsg & Chr(13) & "Bit 1 ON: (2) Only show script calls"
+ End If
+ If GetBit(nDebug, 3) Then
+ cErrMsg = cErrMsg & Chr(13) & "Bit 2 ON: (4) Don't show filename_caps error modal messages"
+ End If
+ MsgBox cErrMsg, 64, "No parameters - Debug Status"
+Else
+ cEXETool = Replace(WScript.ScriptFullName, WScript.ScriptName, "filename_caps.exe")
+ If GetBit(nDebug, 1) And Not GetBit(nDebug, 2) And Not FileSystemObject.FileExists( filename_caps_log ) Then
+ FileSystemObject.CreateTextFile( filename_caps_log )
+ End If
+
+ For i = 0 To WScript.Arguments.Count-1
+ scanDirs( WScript.Arguments(i) )
+ Next
+End If
+
+WScript.Quit(nExitCode)
+
+
+Private Sub scanDirs( tcArgument )
+ Dim omFolder, oFolder
+ If FileSystemObject.FolderExists( tcArgument ) Then
+ '-- Es un directorio
+ Set omFolder = FileSystemObject.GetFolder( tcArgument )
+ For Each oFile IN omFolder.Files
+ evaluateFile( oFile.Path )
+ Next
+ For Each oFolder IN omFolder.SubFolders
+ scanDirs( oFolder.Path )
+ Next
+ Else
+ '-- Es un archivo
+ evaluateFile( tcArgument )
+ End If
+End Sub
+
+
+Private Sub evaluateFile( tcFile )
+ cFlagGenerateLog = "'0'"
+ cFlagDontShowErrMsg = "'0'"
+ cFlagShowCall = "'0'"
+ If GetBit(nDebug,1) Then
+ cFlagGenerateLog = "'1'"
+ End If
+ If GetBit(nDebug,2) Then
+ cFlagJustShowCall = "1"
+ End If
+ If GetBit(nDebug,3) Then
+ cFlagDontShowErrMsg = "'1'"
+ End If
+
+ cCMD = "DO '" & cEXETool & "' WITH '" & tcFile & "','','F','',.F.," & cFlagDontShowErrMsg
+ If cFlagJustShowCall = "1" Then
+ MsgBox cCMD, 0, "PARAMETROS ENVIADOS"
+ Else
+ oVFP9.DoCmd( cCMD )
+ 'nExitCode = oVFP9.Eval("_SCREEN.ExitCode")
+ End If
+End Sub
+
+
+Function GetBit(lngValue, BitNum)
+ Dim BitMask
+ If BitNum < 32 Then BitMask = 2 ^ (BitNum - 1) Else BitMask = "&H80000000"
+ GetBit = CBool(lngValue AND BitMask)
+End Function
diff --git a/FileName_Caps/filename_caps.cfg b/FileName_Caps/filename_caps.cfg
new file mode 100644
index 0000000..40a8b55
--- /dev/null
+++ b/FileName_Caps/filename_caps.cfg
@@ -0,0 +1,25 @@
+*--------------------------------------------------------------------------------------
+* FILENAME_CAPS.CFG
+*
+* FORMATO DE MÁSCARAS:
+* --------------------
+* filemask=FileName.Ext:FileNameCAPS.ExtCAPS
+* Donde: FileName ==> Es el nombre del archivo
+* Ext ==> Es la extensión
+* FileNameCAPS ==> (U)ppercase, (L)owercase, (P)roper, (M)atch, (N)o change
+* ExtCAPS ==> (U)ppercase, (L)owercase, (P)roper, (M)atch, (N)o change
+*
+* EJEMPLOS DE MÁSCARAS:
+* ---------------------
+* filemask=*.PDF:U.L ==> Convierte los archivos PDF a
+* filemask=*.DOT:L.U ==> Convierte los archivos DOT a
+* filemask=*.PRG:C.L ==> Convierte un archivo específico a
+* filemask=EJeMPLo.ini:M.U ==> Convierte un archivo específico a
+* filemask=EjEmPlO.ini:P.U ==> Convierte un archivo específico a
+*
+* IMPORTANTE:
+* -----------
+* LAS CONVERSIONES SE REALIZAN EN EL ORDEN QUE SE PONGAN, COMENZANDO POR ARRIBA.
+*--------------------------------------------------------------------------------------
+filemask=README.ini:M.M
+filemask=*.*:N.L
diff --git a/FileName_Caps/filename_caps.prg b/FileName_Caps/filename_caps.prg
new file mode 100644
index 0000000..7c07146
--- /dev/null
+++ b/FileName_Caps/filename_caps.prg
@@ -0,0 +1,210 @@
+*--------------------------------------------------------------------------------------------------------------
+*-- FileName_Caps.PRG
+*-- CAPITALIZA EL NOMBRE Y EXTENSIÓN DEL ARCHIVO INDICADO SEGÚN LA CONFIGURACIÓN INDICADA
+*-- Fernando D. Bozzo - 24/12/2013
+*--------------------------------------------------------------------------------------------------------------
+* EJEMPLOS CON MÁSCARAS IN-LINE (SIN ARCHIVO CONFIG):
+* filename_caps( 'un_EjeMplo.PrG', '*.pRg:M.M' ) ==> 'un_EjeMplo.PrG'
+* filename_caps( 'un_EjeMplo.PrG', '*.pRg:U.L' ) ==> 'UN_EJEMPLO.prg'
+* filename_caps( 'un_EjeMplo.PrG', '*.pRg:P.U' ) ==> 'Un_ejemplo.PRG'
+* filename_caps( 'UN_EJEMPLO.PRG', 'un_EjeMplo.pRg:M.M' ) ==> 'un_EjeMplo.pRg'
+*
+* EJEMPLO CON MÁSCARAS EN ARCHIVO CONFIG 'filename_caps.cfg':
+* filemask=*.TXT:P.L
+* filemask=*.PDF:U.L
+* filemask=*.APP:P.U
+* filemask=un_EjeMplo.pRg:M.M
+*
+* filename_caps( 'UN_EJEMPLO.TXT', 'filename_caps.cfg', 'F' ) ==> 'Un_ejemplo.prg'
+* filename_caps( 'un_ejemplo.PDF', 'filename_caps.cfg', 'F' ) ==> 'UN_EJEMPLO.prg'
+* filename_caps( 'un_ejemplo.prg', 'filename_caps.cfg', 'F' ) ==> 'Un_ejemplo.PRG'
+* filename_caps( 'UN_EJEMPLO.PRG', 'filename_caps.cfg', 'F' ) ==> 'un_EjeMplo.PrG'
+*--------------------------------------------------------------------------------------------------------------
+* PARÁMETROS: (!=Obligatorio | ?=Opcional) (@=Pasar por referencia | v=Pasar por valor) (IN/OUT)
+* tcFileName (!v IN ) Archivo a capitalizar
+* tcFileMask (?v IN ) Mascara de archivo o archivo de configuración de máscaras (U,L,P,N,M)
+* => Significado: (U)pper,(L)ower,(P)roper,(M)atch,(N)one
+* tcFileMaskType (?v IN ) 'M' o nada=FileMask es una máscara, 'F'=FileMask es un archivo config.
+* tcLog (?@ OUT) Log generado por este programa
+* tlRelanzarError (?v IN ) Indica si el error se debe relanzar (THROW) o no
+* tcDontShowErrors (?v IN ) '1'=Don't show errors, Otherwise=Show errors
+*--------------------------------------------------------------------------------------------------------------
+LPARAMETERS tcFileName, tcFileMask, tcFileMaskType, tcLog, tlRelanzarError, tcDontShowErrors
+
+#DEFINE CR_LF CHR(13)+CHR(10)
+
+LOCAL lcFileName ;
+ , loFNC AS cl_FileName_Caps OF FileName_Caps.prg ;
+ , loEx AS EXCEPTION
+
+loFNC = CREATEOBJECT("cl_FileName_Caps")
+lcFileName = loFNC.Capitalize( tcFileName, tcFileMask, tcFileMaskType, tcLog, tlRelanzarError, tcDontShowErrors )
+
+RETURN lcFileName
+
+
+DEFINE CLASS cl_FileName_Caps AS Custom
+
+ PROCEDURE Capitalize
+ LPARAMETERS tcFileName, tcFileMask, tcFileMaskType, tcLog, tlRelanzarError, tcDontShowErrors
+
+ TRY
+ LOCAL loEx AS EXCEPTION, laMasks(1,4), lcDefinition, lcFileDef, lcMaskDef, laLines(1), lcMenErr ;
+ , I, X, lcName, lcExt, lcPath, lcFileName, laFile(1,5), lcLogFile, lcSys16, lnPosProg ;
+ , loFSO AS Scripting.FileSystemObject
+
+ loEx = NULL
+ loFSO = CREATEOBJECT('Scripting.FileSystemObject')
+ tcFileMaskType = EVL(tcFileMaskType,'M')
+ lcFileName = tcFileName
+ lcLogFile = FORCEEXT(SYS(16),'LOG')
+ tcLog = ''
+ tcDontShowErrors = EVL( tcDontShowErrors, '0' )
+
+ IF EMPTY(tcFileMask)
+ IF tcFileMaskType <> 'F'
+ tcLog = tcLog + CR_LF + '- No hay máscara definida ni archivo de configuración'
+ EXIT && No se indicó nada que hacer
+ ELSE
+ lcSys16 = SYS(16)
+ IF LEFT(lcSys16,10) == 'PROCEDURE '
+ lnPosProg = AT(" ", lcSys16, 2) + 1
+ ELSE
+ lnPosProg = 1
+ ENDIF
+
+ tcFileMask = FORCEEXT( SUBSTR( lcSys16, lnPosProg ), 'CFG' )
+ tcLog = tcLog + CR_LF + '- Se usará el archivo de configuración [' + tcFileMask + ']'
+ IF NOT FILE(tcFileMask)
+ ERROR 'El archivo de configuración de FileName_CAPS [' + tcFileMask + '] no existe!'
+ ENDIF
+ ENDIF
+ ENDIF
+
+ IF tcFileMaskType == 'M' && Máscara in-line
+ *-- Estructura: Filename.Ext:FNameMask.ExtMask;...
+ tcLog = tcLog + CR_LF + '- Máscaras definidas: [' + tcFileMask + ']'
+ FOR I = 1 TO OCCURS( ';', tcFileMask + ';' )
+ lcDefinition = GETWORDNUM( tcFileMask + ';', I, ';' )
+ lcFileDef = GETWORDNUM( lcDefinition, 1, ':' )
+ lcMaskDef = GETWORDNUM( lcDefinition, 2, ':' )
+ laMasks(I,1) = JUSTSTEM( lcFileDef )
+ laMasks(I,2) = JUSTEXT( lcFileDef )
+ laMasks(I,3) = JUSTSTEM( lcMaskDef )
+ laMasks(I,4) = JUSTEXT( lcMaskDef )
+ ENDFOR
+ ELSE && Archivo de configuración
+ *-- Estructura:
+ * filemask=Filename.Ext:FilenameCap.ExtCap => Cap: (U)pper,(L)ower,(P)roper,(M)atch,(N)one
+ * filemask=*.PDF:U.L ==>
+ * filemask=*.DOT:L.U ==>
+ * filemask=*.PRG:C.N ==>
+ * filemask=EjEmPlO.iNi:C.N ==>
+ X = 0
+ FOR I = 1 TO ALINES( laLines, FILETOSTR( tcFileMask ), 1+4 )
+ IF LOWER( LEFT( laLines(I), 8 ) ) == 'filemask'
+ tcLog = tcLog + CR_LF + '- Se encontró la máscara: [' + laLines(I) + ']'
+ X = X + 1
+ lcDefinition = GETWORDNUM( laLines(I), 2, '=' )
+ lcFileDef = GETWORDNUM( lcDefinition, 1, ':' )
+ lcMaskDef = GETWORDNUM( lcDefinition, 2, ':' )
+ DIMENSION laMasks(X,4)
+ laMasks(X,1) = JUSTSTEM( lcFileDef ) && Name
+ laMasks(X,2) = JUSTEXT( lcFileDef ) && Ext
+ laMasks(X,3) = JUSTSTEM( lcMaskDef ) && Name Mask
+ laMasks(X,4) = JUSTEXT( lcMaskDef ) && Ext Mask
+ ENDIF
+ ENDFOR
+ ENDIF
+
+ *-- FileName: "c:\desa\sourcesafe\myfile.ext"
+ lcPath = JUSTPATH( lcFileName )
+ lcName = JUSTSTEM( lcFileName )
+ lcExt = JUSTEXT( lcFileName )
+
+ FOR I = 1 TO ALEN( laMasks, 1 )
+ IF LIKE( UPPER( FORCEEXT( laMasks(I,1), laMasks(I,2) ) ), UPPER( FORCEEXT( lcName, lcExt ) ) )
+ *-- EVALUACIÓN DEL NOMBRE
+ DO CASE
+ CASE UPPER(laMasks(I,3)) == 'U'
+ lcFileName = UPPER(lcName)
+ CASE UPPER(laMasks(I,3)) == 'L'
+ lcFileName = LOWER(lcName)
+ CASE UPPER(laMasks(I,3)) == 'P'
+ lcFileName = PROPER(lcName)
+ CASE UPPER(laMasks(I,3)) == 'N'
+ lcFileName = lcName
+ OTHERWISE && (M)atch: Tal cual aparece definido
+ IF '?' $ laMasks(I,1) OR '*' $ laMasks(I,1)
+ ERROR 'Para (M)atch no puede usar máscara "' + laMasks(I,1) + '"'
+ ENDIF
+ lcFileName = laMasks(I,1)
+ ENDCASE
+
+ *-- EVALUACIÓN DE LA EXTENSIÓN
+ DO CASE
+ CASE UPPER(laMasks(I,4)) == 'U'
+ lcFileName = FORCEEXT( lcFileName + '.' + lcExt, UPPER(lcExt) )
+ CASE UPPER(laMasks(I,4)) == 'L'
+ lcFileName = FORCEEXT( lcFileName + '.' + lcExt, LOWER(lcExt) )
+ CASE UPPER(laMasks(I,4)) == 'P'
+ lcFileName = FORCEEXT( lcFileName + '.' + lcExt, PROPER(lcExt) )
+ CASE UPPER(laMasks(I,4)) == 'N'
+ lcFileName = FORCEEXT( lcFileName + '.' + lcExt, lcExt )
+ OTHERWISE && (M)atch: Tal cual aparece definido
+ IF '?' $ laMasks(I,1) OR '*' $ laMasks(I,1)
+ ERROR 'Para (M)atch no puede usar máscara "' + laMasks(I,1) + '"'
+ ENDIF
+ lcFileName = FORCEEXT( lcFileName + '.' + lcExt, laMasks(I,2) )
+ ENDCASE
+
+ lcFileName = FORCEPATH( lcFileName, lcPath )
+ tcLog = tcLog + CR_LF + '- El archivo se debe renombrar a [' + lcFileName + ']'
+ EXIT
+ ENDIF
+ ENDFOR
+
+ IF ADIR( laFile, lcFileName, '', 1 ) > 0 AND laFile(1,1) <> JUSTFNAME(lcFileName)
+ loFSO.MoveFile( FORCEPATH( laFile(1,1), JUSTPATH(lcFileName) ), lcFileName )
+ tcLog = tcLog + CR_LF + ' => Se renombrará a [' + lcFileName + ']'
+ ELSE
+ tcLog = tcLog + CR_LF + ' => No se renombrará a [' + lcFileName + '] porque ya estaba correcto.'
+ ENDIF
+
+
+ CATCH TO loEx
+ IF tlRelanzarError THEN
+ THROW
+ ELSE
+ IF '800a0046:' $ loEx.Details
+ tcLog = tcLog + CR_LF + ' => No se renombrará a [' + lcFileName + '] porque el archivo estaba en uso o no se puede acceder a el.'
+ ENDIF
+
+ lcMenErr = 'ERROR ' + TRANSFORM(loEx.ERRORNO) + ', ' + loEx.MESSAGE + CHR(13) ;
+ + loEx.PROCEDURE + ', line ' + TRANSFORM(loEx.LINENO) + CHR(13) ;
+ + loEx.LINECONTENTS
+
+ IF TRANSFORM(tcDontShowErrors) # '1' THEN
+ MESSAGEBOX( lcMenErr, 0+16+4096, 'ATENCIÓN!! Ha ocurrido un error al capitalizar', 600000 )
+ ENDIF
+ ENDIF
+
+ FINALLY
+ loFSO = NULL
+ tcFileName = lcFileName
+
+ *-- Si existe FileName_Caps.LOG, lo actualiza
+ IF FILE(lcLogFile)
+ IF NOT EMPTY(lcMenErr)
+ tcLog = tcLog + CR_LF + CR_LF + lcMenErr
+ ENDIF
+
+ STRTOFILE( tcLog, lcLogFile, 1 )
+ ENDIF
+
+ ENDTRY
+
+ RETURN lcFileName
+ ENDPROC
+
+ENDDEFINE && CLASS cl_FileName_Caps AS Custom