FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour cFWGetDir: Nueva funcion a mejorar
Posts: 211
Joined: Wed Jul 16, 2008 12:59 PM
cFWGetDir: Nueva funcion a mejorar
Posted: Sat Aug 17, 2013 03:59 PM
Amigos del foro:
En base al ejemplo xBrwDisk.prg construí una funcion similar a cGetDir()

Ejemplo con cGetDir()


Ejemplo con cFWGetDir()


Si no hay otra mejor, AYUDENME a mejorarla.

CARACTERISTICAS:
- Se puede indicar la carpeta inical (si es vacio, mostrara las unidades de disco)
- Puede crear carpetas, DUPLICARLAS, renombrarlas, eliminarlas
- Se puede indicar que botones va a mostrar
- Puede mostrar, tambien, archivos

NOTA: no adjunto los bitmaps, pero pueden colocarlas a su gusto.

Aca el codigo
Code (fw): Select all Collapse
//-------------------------------------------------------------------------------------------------------------//
//Funcion cFWGetDir
//-------------------------------------------------------------------------------------------------------------//
function cFWGetDir(nTop, nLeft, nBottom, nRight, cCaption,;
                 cPath,;
         lVerColSize,lVerColDate,lVerColTime,lVerColAttr,;
         lSoloFolder,;
         lBtnAdd,lBtnDuplicate,lBtnRename,lBtnDelete)

   local oDlg, oCtrl, oBrw, oTree, oItem, oFont, b
   local cNuevaCarpeta := Space(64)

   DEFAULT nTop:=10,;
           nLeft:=10,;
       nBottom:=640,;
       nRight:=440,;
           cCaption:="Seleccione una carpeta"
   DEFAULT lVerColSize:=.T.,;
           lVerColDate:=.T.,;
       lVerColTime:=.T.,;
       lVerColAttr:=.T.
   DEFAULT lSoloFolder := .T.
   DEFAULT lBtnAdd := .T.,;
       lBtnDuplicate := .T.,;
       lBtnRename := .T.,;
       lBtnDelete := .T.

   oTree := MakeTree(cPath,lSoloFolder)

   DEFINE FONT oFont NAME 'TAHOMA' SIZE 0,-12
   DEFINE DIALOG oDlg SIZE nRight,nBottom PIXEL ;
      TITLE cCaption ;
      FONT oFont

   @ 10,10 XBROWSE oBrw SIZE nRight/2-10-10,nBottom/2-10-10 -10 PIXEL OF oDlg //NOBORDER

   //oBrw:lHScroll := .F.
   oBrw:lHeader := .F.
   oBrw:lRecordSelector := .F.
   oBrw:SetTree( oTree, { ".\bitmaps\open2.bmp", ;
                          ".\bitmaps\folder.bmp", ;
                          ".\bitmaps\onepage2.bmp" } )
   oBrw:bKeyChar  := { |nKey| If( nKey == VK_RETURN .and. ! Empty( oBrw:oTreeItem:bAction ), ;
                                Eval( oBrw:oTreeItem:bAction, oBrw:oTreeItem ), nil ) }


   WITH OBJECT oBrw:aCols[ 1 ]

      :AddBmpFile( ".\bitmaps\hdrive.bmp" )
      :nWidth     := 300
      :cHeader    := 'File/Folder'
      b           := :bLDClickData

      :bLDClickData  := { |r,c,f,o| ToggleFolder( r,c,f,o,b ) }

      :bBmpData   := { || If( ':' $ oBrw:oTreeItem:cPrompt, 4, ;
                          If( 'D' $ oBrw:oTreeItem:Cargo[ 5 ], ;
                          If( oBrw:oTreeItem:lOpened, 1, 2 ), 3 ) ) }
      :bStrData   := { || oBrw:oTreeItem:cPrompt}

   END

   if lVerColSize
      ADD TO oBrw DATA oBrw:oTreeItem:Cargo[ 2 ] ;
         PICTURE '@EZ 999,999,999' HEADER 'Bytes'
   endif
   if lVerColDate
      ADD TO oBrw DATA oBrw:oTreeItem:Cargo[ 3 ] HEADER 'Date'
   endif
   if lVerColTime
      ADD TO oBrw DATA oBrw:oTreeItem:Cargo[ 4 ] HEADER 'Time'
   endif
   if lVerColAttr
      ADD TO oBrw DATA oBrw:oTreeItem:Cargo[ 5 ] HEADER 'Attr'
   endif

   oBrw:CreateFromCode()

   @ nBottom/2-10-5, nRight/2-10-35 BUTTONBMP oCtrl;
     SIZE 35, 12 OF oDlg;
     ACTION oDlg:End(0);
     PROMPT SPACE(3)+"Cancel";
     BITMAP 'EXIT'PIXEL CANCEL TEXTRIGHT

   @ oCtrl:nTop, oCtrl:nLeft-35-1 BUTTONBMP oCtrl;
     SIZE 35, 12 OF oDlg;
     ACTION oDlg:End(1);
     PROMPT SPACE(3)+"Select";
     BITMAP 'V' PIXEL DEFAULT TEXTRIGHT

   if lBtnDelete
   @ oCtrl:nTop, oCtrl:nLeft-14-1 BUTTONBMP oCtrl;
     SIZE 14, 12 OF oDlg;
     ACTION (if(MsgNoYes("Eliminar carpeta: "+oBrw:oTreeItem:Cargo[1]),;
            if(DirRemove(oBrw:oTreeItem:Cargo[6])=0,;
           oBrw:oTreeItem:Delete(oBrw:oTreeItem:Parent():oTree),;
           MsgStop("NO se pudo eliminar: "+oBrw:oTreeItem:Cargo[1])),;
            NIL),;
         oBrw:SetFocus());
      BITMAP 'Del' PIXEL
      oCtrl:cToolTip:="Elimina la carpeta seleccionada"
   endif

   if lBtnRename
   @ oCtrl:nTop, oCtrl:nLeft-14-1 BUTTONBMP oCtrl;
     SIZE 14, 12 OF oDlg;
     ACTION (cNuevaCarpeta:=PADR(oBrw:oTreeItem:Cargo[1],64),;
             if(MsgGet( "System", "Renombrar: "+oBrw:oTreeItem:Cargo[1], @cNuevaCarpeta ),;
            if(!(UPPER(ALLTRIM(oBrw:oTreeItem:Cargo[6]))==UPPER(cFilePath(oBrw:oTreeItem:Cargo[6])+ALLTRIM(cNuevaCarpeta))).AND.;
           FRename(ALLTRIM(oBrw:oTreeItem:Cargo[6]),cFilePath(oBrw:oTreeItem:Cargo[6])+ALLTRIM(cNuevaCarpeta))=0,;
           (oBrw:oTreeItem:SetText( RTRIM(cNuevaCarpeta) ),;
            oBrw:oTreeItem:Cargo[1]:=RTRIM(cNuevaCarpeta),;
            oBrw:oTreeItem:Cargo[6]:=cFilepath(oBrw:oTreeItem:Cargo[6])+ALLTRIM(cNuevaCarpeta)),;
           MsgStop("NO se pudo renombrar: "+oBrw:oTreeItem:Cargo[1])),;
            NIL),;
         oBrw:SetFocus());
      BITMAP 'Edit' PIXEL
      oCtrl:cToolTip:="Cambia el nombre de la carpeta seleccionada"
   endif

   if lBtnDuplicate
   @ oCtrl:nTop, oCtrl:nLeft-14-1 BUTTONBMP oCtrl;
     SIZE 14, 12 OF oDlg;
     ACTION (if(DirDuplicate(oBrw:oTreeItem:Cargo[6]),;
        oBrw:oTreeItem:Parent( ):SetTree( SubTree( oBrw:oTreeItem:Parent( ), lSoloFolder ) ),;
        MsgStop("NO se pudo duplicar: "+oBrw:oTreeItem:Cargo[1])),;
         oBrw:SetFocus());
      BITMAP 'Duplicate' PIXEL
      oCtrl:cToolTip:="Duplica la carpeta seleccionada"
   endif

   if lBtnAdd
   @ oCtrl:nTop, oCtrl:nLeft-14-1 BUTTONBMP oCtrl;
     SIZE 14, 12 OF oDlg;
     ACTION (cNuevaCarpeta:=PADR(oBrw:oTreeItem:Cargo[1],64),;
             if(MsgGet( "System", "Nueva carpeta", @cNuevaCarpeta ),;
            if(MakeDir( oBrw:oTreeItem:Cargo[ 6 ] + Chr(92) + ALLTRIM(cNuevaCarpeta))=0,;
           (oBrw:oTreeItem:SetTree( SubTree( oBrw:oTreeItem, lSoloFolder ) ),;
            oBrw:oTreeItem:bAction:=0,;
            if(oBrw:oTreeItem:lOpened,;
               NIL,;
               oBrw:oTreeItem:Toggle() )),;
           MsgStop("NO se pudo crear: "+ALLTRIM(cNuevaCarpeta))),;
            NIL),;
         oBrw:SetFocus());
      BITMAP 'Add' PIXEL
      oCtrl:cToolTip:="Crea una nueva carpeta"

   endif

   ACTIVATE DIALOG oDlg CENTER

return if(oDlg:nResult=0,NIL,oBrw:oTreeItem:Cargo[ 6 ])

//----------------------------------------------------------------------------//
static function ToggleFolder( r, c, f, oCol, b )

   local oBrw  := oCol:oBrw
   local oItem := oBrw:oTreeItem

   If ! oItem:lOpened .and. ! Empty( oItem:bAction )
      Eval( oItem:bAction, oItem )
   endif

   if b != nil
      Eval( b, r, c, f, oCol )
   endif

return nil

//----------------------------------------------------------------------------//
static function MakeTree(cFolder,lSoloFolder)

   local oTree, oItem, n, nItems := 0
   local aDrives  := aDrives( 2 )   // Hard disks
   local cNDrive

   DEFAULT lSoloFolder := .T.

   TREE oTree

   if EMPTY(cFolder)// = NIL
      for n := 1 to Len( aDrives )

     cNDrive:=GetVolInfo( aDrives[ n ]+"\" )

         TREEITEM oItem PROMPT if( EMPTY(cNDrive),"Disco local",cNDrive ) +" ("+ aDrives[ n ] +")"
         oItem:Cargo := { aDrives[ n ], 0, CtoD( '' ), Space( 8 ), 'D', ;
                          aDrives[ n ] }

         oItem:bAction  := { |o| o:SetTree( SubTree( o, lSoloFolder ) ), o:bAction := nil }

      next
   else
      TREEITEM oItem PROMPT cFileNoPath(cFolder)

      oItem:Cargo := { cFileNoPath(cFolder), 0, CtoD( '' ), Space( 8 ), 'D', ;
                        cFolder }

      oItem:bAction := { |o| o:SetTree( SubTree( o, lSoloFolder ) ), o:bAction := nil }
      oItem:SetTree( SubTree( oItem, lSoloFolder ) )
      oItem:Toggle()

   endif

   ENDTREE

return oTree

//----------------------------------------------------------------------------//

static function SubTree( oParent,lSoloFolder )

   local oTree, n, oItem, nLevel, nItems := 0
   local cFolder := oParent:Cargo[ 6 ]
   local aDir := Directory( cFolder + '\*.*', 'D' )

   DEFAULT lSoloFolder := .T.

   nLevel := oParent:nLevel + 1

   TREE oTree
   for n := 1 to Len( aDir )
      if ! ( aDir[ n ][ 1 ] = '.' ) .AND. (!lSoloFolder .OR. 'D' $ aDir[ n ][ 5 ] )

         TREEITEM oItem PROMPT aDir[ n ][ 1 ]

         oItem:nlevel := nLevel
         oItem:Cargo  := aDir[ n ]

         AAdd( oItem:Cargo, cFolder + Chr(92) + aDir[ n ][ 1 ] )

         if 'D' $ aDir[ n ][ 5 ]
            oItem:bAction  := { |o| o:SetTree( SubTree( o, lSoloFolder ) ), o:bAction := nil }
         else
            oItem:bAction  := { |o| MsgInfo( o:cPrompt ) }
         endif
         nItems++
      endif
   next
   /*
   if nItems == 0
      n--
      TREEITEM oItem PROMPT ''
      oItem:nlevel := nLevel
      aDir[ n ][ 5 ] := 'A'
      oItem:Cargo  := { '', 0, CToD( '' ), Space(8), ' ', '' }
      AAdd( oItem:Cargo, cFolder + Chr(92) + aDir[ n ][ 1 ] )
   endif
   */
   ENDTREE

return oTree

//----------------------------------------------------------------------------//

//function DirDuplicate( cName, cPath )
function DirDuplicate( cPath )//16/08/13
local cPathOrg,cFolder,cFolderCpy,cCpy, aFiles, n:=0

   cPath:=RTRIM(cPath)
   if Right(cPath,1)="/"
      cPath:=Left(cPath,len(cPath)-1)
   endif
   cPathOrg:=cPath

   cFolder:=cFileNoPath(cPath)
   cPath:=cFilePath(cPath)

   WHILE .T.
      cCpy := " (Copia " + cValToChar( ++n ) + ")"
      cFolderCpy := cFolder + cCpy
      if !IsDirectory( cPath + cFolderCpy ) .OR. n > 1000
         EXIT
      ENDIF
   END

   cPath := cPath + cFolderCpy

   IF lRMkDir( cPath )
      aDir( cPathOrg + "\*.*", aFiles:=ARRAY( aDir(cPathOrg + "\*.*") ) )
      aEval( aFiles, {|cFile| FileCopy(cPathOrg + "\" + cFile, cPath + "\" + cFile) } )
   else
      MsgStop("No se puede crear la carpeta de la Base de Datos copiada","DirDuplicate(..)")
      Return .F.
   EndIf

Return .T.

//FIN Funcion cFWGetDir ----------------------------------------------------------------------------//




Atentamente,

Rolando
Cochabamba - Bolivia
FWH 1109 - xHarbour 1.1.0 (SimpLex) - BCC58
Posts: 1076
Joined: Fri Oct 07, 2005 10:41 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Sat Aug 17, 2013 05:41 PM

Excelente aporte

William, Morales

Saludos



méxico.sureste
Posts: 1364
Joined: Wed Jun 21, 2006 12:39 AM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Sat Aug 17, 2013 08:00 PM

Muy buen trabajo. Felicitaciones !!!

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Mon Aug 19, 2013 11:00 AM

Rolando,

Muy bien, gracias! :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 211
Joined: Wed Jul 16, 2008 12:59 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Mon Aug 19, 2013 01:07 PM
Mejorando la funcion..

Pueden descargar un ejemplo completo desde el siguiente enlace, vaciarlo a la carpeta SAMPLES y construirlo.

http://www.sauro-sys.com/Source/sampleFWGD.zip

Para mi funciona... espero que para ustedes tambien.

Atentamente,

Rolando
Cochabamba - Bolivia
FWH 1109 - xHarbour 1.1.0 (SimpLex) - BCC58
Posts: 2170
Joined: Fri Jul 18, 2008 01:24 AM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Mon Aug 19, 2013 10:21 PM

Rolando,
Excelente aporte. Quizás una pequeña mejora sería que los botones para crear carpeta, cambiarle nombre, duplicarla, o borrarla, aparezcan hasta que has abierto una unidad de disco. Lo otro sería que al crear una nueva carpeta, el puntero se coloque sobre esa carpeta.
Saludos, y nuevamente felicitaciones.

Francisco J. Alegría P.

Chinandega, Nicaragua.



Fwxh-MySql-TMySql
Posts: 211
Joined: Wed Jul 16, 2008 12:59 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Wed Aug 21, 2013 07:56 PM
Francisco:

Buenas observaciones, lo hare en cuanto tenga tiempo.

Por el momento me dedique a completar la opcion de ver los equipos de red.

Ahora ya se puede ver los equipos de la red y sus recursos.
Pueden descargar, nuevamente, el archivo comprimido desde el siguiente enlace.

http://www.sauro-sys.com/Source/sampleFWGD.zip

NOTA:
Les comento que la funcion: DriveType( [<cDrive>] ) de xharbour, a veces NO detecta bien los DISCOS de RED, devuelve 9 (Unknown drive); si devuelve 5 (Network drive) se mostrara el icono correcto.

Para mi funciona... espero que para ustedes tambien.

Atentamente,

Rolando
Cochabamba - Bolivia
FWH 1109 - xHarbour 1.1.0 (SimpLex) - BCC58
Posts: 625
Joined: Wed Mar 14, 2007 06:49 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Wed Aug 21, 2013 10:55 PM
Rolando:
Excelente trabajo, no he podido compilarlo, me marca error

En el primer ejemplo:
Code (fw): Select all Collapse
testFWGD.prg(281) Error E0021  Incorrect number of arguments in AT


y el mismo fallo en el segundo:

Code (fw): Select all Collapse
[1]:Harbour.Exe testFWGD.prg  /m /n0 /gc0 /es2 /iZ:\FWH\include /iZ:\Harbour\Include /dHB_API_MACROS /dHB_FM_STATISTICS_OFF /dHB_STACK_MACROS /iZ:\Harbour\Contrib\What32\Include /oObj\testFWGD.c
Harbour 3.0.0 (Rev. 16951)
Copyright (c) 1999-2011, http://harbour-project.org/
Compiling 'testFWGD.prg'...
testFWGD.prg(286) Error E0021  Incorrect number of arguments in AT 
Passed: 3, expected: 2
1 error


Esta es la linea de referencia:
Code (fw): Select all Collapse
TREEITEM oItem PROMPT cFileNoPath(cNDrive) + ' en "'+SUBSTR(cNDrive,3,AT("\",cNDrive,3)-3)+'" ' +" ("+ aDrives[ n ] +")"


Según la documentación de Harbour :_
Code (fw): Select all Collapse
     AT(<cBúsqueda>, <cDestino>) --> nPosición

 Argumentos

     <cBúsqueda> es la subcadena de caracteres que se va a buscar.

     <cDestino> es la cadena de caracteres en la que se realiza la
     búsqueda.

 Devuelve

     AT() devuelve la posición de la primera aparición de <cBúsqueda> dentro
     de <cDestino>, como valor numérico entero. Si no se encuentra
     <cBúsqueda>, AT() devuelve cero.

 Descripción

     AT() es una función de tratamiento de caracteres que se utiliza para
     determinar la posición de la primera aparición de una subcadena dentro
     de otra cadena. Si sólo necesita saber si una subcadena se encuentra
     dentro de otra, utilice el operador $. Para encontrar la última
     aparición de una cadena dentro de otra, utilice RAT().


No se si sea porque compilo con Harbour 3.0.0 (Rev. 16951)..

Saludos..
Soluciones y Diseño de Software
Damos Soluciones...

I.S.C. Victor Daniel Cuatecatl Leon
Director y Diseñador de Proyectos

http://www.soldisoft.unlugar.com
http://www.sisa.unlugar.com
danyleon82@hotmail.com
www.facebook.com/victordaniel.cuatecatlleon
Posts: 1364
Joined: Wed Jun 21, 2006 12:39 AM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Wed Aug 21, 2013 11:55 PM
Victor, haciendo este cambio funciona para Harbour

Code (fw): Select all Collapse
TREEITEM oItem PROMPT cFileNoPath(cNDrive) + ' en "'+SUBSTR(cNDrive,3,AT("\",cNDrive )-3)+'" ' +" ("+ aDrives[ n ] +")"


Saludos
Posts: 625
Joined: Wed Mar 14, 2007 06:49 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Thu Aug 22, 2013 12:40 AM
Perfecto, ya pude compilar y probar, me atreví a hacer una simple mejora para encontrar tambien carpetas ocultas y de sistema, ya que a veces es necesario trabajar con ellas modificando en la línea 360.

Code (fw): Select all Collapse
DIRECTORY( cFolder + '\*.*', 'DHS' )


Perooo.. tambien tienes el mismo problemita que yo con el scroll horizontal del xbrowse cuando el árbol de items es muy extenso ya no puedes avanzar.



aquí lo comento más detalladamente, sin encontrar aún solución:

http://forums.fivetechsupport.com/viewtopic.php?f=6&t=26932

Saludos..
Soluciones y Diseño de Software
Damos Soluciones...

I.S.C. Victor Daniel Cuatecatl Leon
Director y Diseñador de Proyectos

http://www.soldisoft.unlugar.com
http://www.sisa.unlugar.com
danyleon82@hotmail.com
www.facebook.com/victordaniel.cuatecatlleon
Posts: 2170
Joined: Fri Jul 18, 2008 01:24 AM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Thu Aug 22, 2013 01:58 AM

Francamente no se, pero no me escribe nada sobre el fichero temporal. He revisado, lo crea bien, pero en blanco.
WAITRUN("COMMAND.COM /C net view > "+cFile ,0)
Las pruebas las hago en una pequeña red que tengo en casa.
Saludos.

Francisco J. Alegría P.

Chinandega, Nicaragua.



Fwxh-MySql-TMySql
Posts: 211
Joined: Wed Jul 16, 2008 12:59 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Thu Aug 22, 2013 03:17 PM
Amigos:

Estuve algo ocupado, pero ya tengo una nueva version:

http://www.sauro-sys.com/Source/sampleFWGD.zip

NOTAS:
- Ya NO usamos DriveType( [<cDrive>] )
- Para evitar el problema del AT(..) ahora se usa TOKEN() (comun en Harbour/xharbour, yo aun uso xHarbour)
- Añadimos nuevos parametros: lHide,lSystem; para ver archivos ocultos o de sistema
- Victor: para el problema del HScroll, por el momento, se deberia/podria cambiar el ancho del dialogo a +- 400
Ejm: cFWGetDir(,,300,400)
- Mejoramos el ejemplo y ahora podemos ver archivos
- Francisco: proba el comando en la consola y ve si hay resultado... porfa me avisas si encuentras la solucion

Atentamente,

Rolando
Cochabamba - Bolivia
FWH 1109 - xHarbour 1.1.0 (SimpLex) - BCC58
Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Thu Aug 22, 2013 06:23 PM

He compilado tu función,
pero al darle doble click en RED LOCAL no hace nada,
solo funciona cuando doy click en Mi Pc,

saludos..

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "
Posts: 1144
Joined: Mon Feb 05, 2007 07:15 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Thu Aug 22, 2013 06:24 PM

perdón: se me paso mencionar, que la prueba la hice en Windows 8.
saludos.

Cesar Cortes Cruz

SysCtrl Software

Mexico



' Sin +- FWH es mejor "
Posts: 1380
Joined: Fri Oct 14, 2005 01:28 PM
Re: cFWGetDir: Nueva funcion a mejorar
Posted: Thu Aug 22, 2013 08:03 PM

Rolando;
interesante aporte

He detectado lo siguiente (con Windows 7):
- Al dar dobleclic sobre en RED LOCAL no hace nada (una red de 3 PCs, todas con W7)
- Desde la opción Completo selecciono una carpeta que debería devolver:
D:\Google Drive\Fuentes y Programas\mgApp\MisAppTools\16Bits\mgByR
devuelve:
D:\Google Drive\Fuentes y Programas\mgApp\MisAppTools\16Bits\mgB

Saludos

Resistencia - "Ciudad de las Esculturas"

Chaco - Argentina