Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Problemas con SelectDirectory (https://www.clubdelphi.com/foros/showthread.php?t=94730)

aguml 15-06-2020 09:28:53

Problemas con SelectDirectory
 
Hola amigos, estoy intentando mostrar una ventana donde pueda seleccionar uno o mas directorios y de momento estoy con SelectDirectory y tengo esto:
Código PHP:

#include <FileCtrl.hpp>

const SELDIRHELP 1000;
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  
String Dir "C:\\Program Files\\CodeGear";
  if (
SelectDirectory(DirTSelectDirOpts() << sdAllowCreate << sdPerformCreate << sdPrompt,SELDIRHELP))
    
Label1->Caption Dir;


Si intento compilar me dice este error:
Código:

[ilink32 Error] Error: Unresolved external '__fastcall Vcl::Filectrl::SelectDirectory(System::UnicodeString&, System::Set<Vcl::Filectrl::TSelectDirOpt, 0, 2>, int)' referenced from C:\USERS\xxx\WIN32\DEBUG\UNIT1.OBJ
Ese codigo está sacado tal cual de la misma ayuda del C++Builder ¿Alguien me puede ayudar?

dec 15-06-2020 09:57:23

Hola a todos,

Mira a ver si esta respuesta de StackOverflow puede servirte. Parece que tienes que "enlazar" de este modo:

Código:

<AllPackageLibs>rtl.lib;vcl.lib;vclx.lib</AllPackageLibs>
Dicho eso, si no me equivoco, el "SelectDirectory" no te permitirá seleccionar más de un directorio al mismo tiempo. Acaso podrías probar con el componente "TFileOpenDialog", que no es el "antiguo" "TOpenDialog". El primero está dentro de la categoría "Vista dialogs".

El componente "TFileOpenDialog", entre otras opciones de utilidad, tiene una opción "fdoPickFolders", pero, también otra opción "fdoAllowMultiselect": con ambas opciones activadas es posible elegir varias carpetas al mismo tiempo.

aguml 15-06-2020 19:33:13

mil gracias, me funcionó perfectamente.
Algo que no veo en ese componente es la opción de filtrar por la extensión ¿se puede igual que en el OpenDialog? ¿como sería?

dec 15-06-2020 20:49:59

Hola a todos,

En efecto, el componente "TFileOpenDialog" cuenta con una propiedad "FileTypes", que, permite filtrar por máscaras, no sólo por extensiones, por ejemplo, podriámos admitir sólo archivos que contuviesen la palabra "index" con una máscara similar a esta: *index* (no es "case sensitive"). Lo malo es que esto no parece funcionar si elegimos la opción "fdpPickFolders", o sea, sólo parece funcionar con archivos.

¿Quieres permitir elegir archivos o directorios? Si es esto último, hay un problemas, porque, el "SelectDirectory" únicamente permite elegir un directorio al mismo tiempo, pero, el "TFileOpenDialog", que, permitiría elegir varios directorios al mismo tiempo, no cuenta con algo como una "máscara" para los nombres de los directorios... de modo que no sé hasta qué punto podrías usar estos componentes.

Lo bueno es que, a las malas, malas, siempre podrías crear tú un componente para esto mismo... costaría más trabajo, ciertamente, pero, a las malas...

aguml 15-06-2020 21:10:27

Uso ambos modos, o sea, tengo un checkboxs el cual decide si busco por archivos o por directorios. Si busco por directorios el filtrado de las extensiones de los archivos lo hago a mano mientras recorro todos los archivos del directorio.
El filtrado del FileOpenDialog lo quiero solo cuando se vaya a seleccionar archivos pero no sé cómo hacerlo. Lo intenté pero no conseguía ni compilar lo que intenté.

dec 16-06-2020 13:20:06

Hola a todos,

Cita:

Empezado por aguml
El filtrado del FileOpenDialog lo quiero solo cuando se vaya a seleccionar archivos pero no sé cómo hacerlo. Lo intenté pero no conseguía ni compilar lo que intenté.

¿Pero al final te hiciste con ello o no? :) Se trata de añadir uno o más tipos de archivo en "FileTypes"...

aguml 16-06-2020 17:40:03

A ver, para cuando quiero seleccionar directorios tengo esto:
Código PHP:

int __fastcall TForm1::GetFilesDir(char *pathint *nArchivos)
{
    
int largoMayor=0;
    
WideString FullPath;

    
/* Con un puntero a DIR abriremos el directorio */
    
DIR *dir;
    
/* en *ent habrá información sobre el archivo que se está "sacando" a cada momento */
    
struct dirent *ent;

    
dir opendir (path);

    
/* Miramos que no haya error */
    
if (dir == NULL)
        
ShowMessage("No puedo abrir el directorio");

    
/* Una vez nos aseguramos de que no hay error, ¡vamos a jugar! */
    /* Leyendo uno a uno todos los archivos que hay */
    
while ((ent readdir (dir)) != NULL)
    {
        
FullPath ent->d_name;

        
/* Nos devolverá el directorio actual (.) y el anterior (..), como hace ls */
        
if ( FullPath != "." && FullPath != ".." )
        {
            
FullPath WideString(path) + "\\" WideString(ent->d_name);
            
/* Una vez tenemos el archivo, lo pasamos a una función para procesarlo. */
            
if(FileExists(FullPath)){  //Esto lo hago para no añadir los directorios a la lista
                
if(CheckBoxExtension->Checked){  //Si está marcado el checkbox de filtrado por extension entro
                    
if(EditExtension->Text == ExtractFileExt(FullPath)){  //Si coincide la extensión entro
                        
ListBoxSeleccionados->Items->Add(FullPath);
                        
largoMayor FullPath.Length();
                        (*
nArchivos)++;
                    }
                }else{  
//Si no tengo marcado el filtrado por extension entro aquí
                    
ListBoxSeleccionados->Items->Add(FullPath);
                    
largoMayor FullPath.Length();
                    (*
nArchivos)++;
                }
            }
        }
    }
    
closedir (dir);
    return 
largoMayor;


Y en el botón tengo esto:
Código PHP:

if(CheckBoxSelDirectorios->Checked){
    for(
int i=0FileOpenDialog1->Files->Counti++){
        
largoMayor GetFilesDir(AnsiString(FileOpenDialog1->Files->Strings[i]).c_str(),&nArchivos);
    }
}else{
    for(
int i=0FileOpenDialog1->Files->Counti++){
        
ListBoxSeleccionados->Items->Add(FileOpenDialog1->Files->Strings[i]);
        if(
FileOpenDialog1->Files->Strings[i].Length() > largoMayor)
            
largoMayor FileOpenDialog1->Files->Strings[i].Length();
        
nArchivos++;
    }


Y en el CheckBox:
Código PHP:

void __fastcall TForm1::CheckBoxSelDirectoriosClick(TObject *Sender)
{
    if(
CheckBoxSelDirectorios->Checked){
        
FileOpenDialog1->Options << fdoPickFolders;
        
CheckBoxExtension->Enabled true;
        
EditExtension->Enabled true;
    }else{
        
FileOpenDialog1->Options >> fdoPickFolders;
        
CheckBoxExtension->Enabled false;
        
EditExtension->Enabled false;
    }


Como puedes ver, para el caso de que vaya a seleccionar archivos no hay ningún tipo de filtrado pero si lo que voy a seleccionar son directorios ahí lo filtro en el bucle de la función que recorre todos los directorios seleccionados.
No se como hacer lo que dices de añadir el filtrado para los archivos y ademas tengo que poder eliminar el filtrado cuando se desmarque el checkbox.


La franja horaria es GMT +2. Ahora son las 09:38:14.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi