Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Saber cuando se crea un archivo nuevo en un directorio (https://www.clubdelphi.com/foros/showthread.php?t=68190)

CHRISTIANHAZ77 30-05-2010 15:41:51

Saber cuando se crea un archivo nuevo en un directorio
 
Hola, queria consultar si alguien sabe, o se puede detectar, si se produce la creacion de un archivo nuevo dentro de un directorio x. Necesito saber esto ya que mi aplicacion debe tomar informacion de otro soft luego que este la crea.
Gracias

escafandra 30-05-2010 18:16:56

Puedes convertir a tu aplicación en una extensión del Shell, para elle debes ser capaz de recibir el mensaje WM_SETTINGCHANGE que se envía al Shell y sus extensiones al producirse cambios. Esas notificaciones se envían mediante la API
SHChangeNotify. En tu caso debes controlar el valor SHCNE_CREATE:

Código:

typedef ULONG(WINAPI *PSHChangeNotifyRegister)(HWND hwnd, int fSources, LONG fEvents, UINT wMsg,
                                    int cEntries, const SHChangeNotifyEntry *pshcne);

typedef BOOL (WINAPI *PSHChangeNotifyDeregister)(ULONG ulID);

// Convertir el formulario en receptor del mensaje WM_SETTINGCHANGE
void __fastcall TForm1::StartNotification()
{
    PSHChangeNotifyRegister SHChangeNotifyRegister =
          (PSHChangeNotifyRegister)GetProcAddress(GetModuleHandle("shell32.dll"), "SHChangeNotifyRegister");

    SHChangeNotifyEntry shCNE;
    shCNE.pidl = 0;
    shCNE.fRecursive = TRUE;

    // Eventos que se van a registrar
    LONG Events =  SHCNE_CREATE |SHCNE_DELETE;

    m_ulSHChangeNotifyRegister = SHChangeNotifyRegister(Handle, SHCNRF_INTERRUPT_LEVEL | SHCNRF_SHELL_LEVEL, Events, WM_USER_SHELLCHANGED, 1, &shCNE);
}


//-------------------------------------------------------------------------
// Responder al mensaje
void __fastcall TForm1::WndProc(Messages::TMessage &Message)
{
  if(Message.Msg == WM_USER_SHELLCHANGED){
    switch(Message.LParam & 0x7FFFFFF)
    {
      case SHCNE_CREATE:
        // tu código dr creación de fichero
        break;
      case SHCNE_DELETE:
        // tu código de destrucción de fichero
        break;
    }
  }
  TForm::WndProc(Message);
}

// Destructor del Form Eliminarnos como extensión del Shell:
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    PSHChangeNotifyDeregister SHChangeNotifyDeregister =
      (PSHChangeNotifyDeregister)GetProcAddress(GetModuleHandle("shell32.dll"), "SHChangeNotifyDeregister");

    if(m_ulSHChangeNotifyRegister)
      SHChangeNotifyDeregister(m_ulSHChangeNotifyRegister);

}


Saludos.

CHRISTIANHAZ77 30-05-2010 21:57:15

gracias
 
Agradezco mucho tu tiempo, almenos se que se puede, no entiendo a simple vista ese codigo pero le voy a dedicar tiempo para tratar de descifrarlo, para que el TFORM pueda recibir o captar esos cambios en donde debe ir el codigo?

escafandra 30-05-2010 22:43:08

En primer lugar decirte que el ejemplo está escrito en C++ Builder, pero es fácilmente trasladable a delphi si es el lenguaje que usas. En segundo lugar, para que tu código sea sensible a WM_SETTINGCHANGE, es decir que reciba ese mensaje junto con el Shell, debes ejecutar el código de la función StartNotification que como ves la he escrito como miembro de Form1. Cuando quieras dejar de de recibir el mensaje WM_SETTINGCHANGE debes ejecutar FormDestroy esto lo puedes hacer cuando quieras dejar de recibir el mensaje o al destruir el form1.

El Resto es la rutina de tratamiento del mensaje, que tendrás que diseñar tu.

Saludos.

Neftali [Germán.Estévez] 31-05-2010 12:23:29

También puede utilizar algun componente que encapsula estecomportamiento y que te será más sencillo de utilizar. Las RxLib, por ejemplo, traen uno llamado RxFolderMonitor, aunque seguro que en Torry puedes encontrar alguno más...

Faust 31-05-2010 18:47:16

Precisamente es algo que estaba a punto de preguntar, pero no me atrevía, pues no había buscado en el foro...

He descargado algunos componentes de torry y creo de delphi about, pero no me satisfacen, pues notifican p. ej. cuando se crea un archivo haciendo clic derecho en el explorador de windows clic en el submenu nuevo y archivo de texto, pero cuando algunos programas crean el archivo, p. ej. al darle guardar como, no lo notifica :mad:...

¿cuál sería un método efectivo para realizar esta tarea?

escafandra 31-05-2010 19:09:28

He encontrado esto. Si tengo un rato, traduzco o que puse en C para complementar y dar una versión mas simple.

Saludos.

egostar 01-06-2010 01:56:33

Cita:

Empezado por escafandra (Mensaje 365764)
He encontrado esto. Si tengo un rato, traduzco o que puse en C para complementar y dar una versión mas simple.

Saludos.

Hola amigo escafandra, te puedes ahorrar el tiempo de la traducción utilizando el componente que viene con Delphi (y que no está instalado) que se llama precisamente TShellChangeNotifier, este componente hasta donde sé viene desde la versión 7 de Delphi, se localiza dentro de la carpeta ShellControls dentro de DEMOS

En Delphi 2007 se localiza en la siguiente ruta

C:\Documents and Settings\All Users\Documentos\RAD Studio\5.0\Demos\DelphiWin32\VCLWin32\ShellControls

Se instalan los siguientes componentes:

TShellTreeView
TShellComboBox
TShellListView
TShellChangeNotifier
(Que es el que nos ocupa en este momento)

Este componente tiene varias opciones en la propiedad NotifyFilters, si lo que quieren es solo ver los archivos nuevos se pone la opción nfWriteChange en true y las demás en false. Si quieres ver los subdirectorios nuevos asignas la opción nfDirNameChange, etc...

Tiene también otra propiedad que es la que indica que directorio quieres monitorear y es la propiedad Root.

Por último en el evento OnChange ya puedes escribir el código que desees para filtrar el archivo que ha sido creado.

También pueden ver este artículo que cuenta con una interesante aplicación Monitoring System Shell Changes using Delphi

Saludos

escafandra 01-06-2010 08:04:22

Cita:

Empezado por egostar (Mensaje 365788)
Hola amigo escafandra, te puedes ahorrar el tiempo de la traducción utilizando el componente que viene con Delphi (y que no está instalado) que se llama precisamente TShellChangeNotifier...

Pues no lo conocía, amigo. Miraré si existe algo parecido en el Builder, aunque creo que no, en las versiones que manejo y que tengo bastante trilladas.

Sabes que no me gusta demasiado depender de componentes y que confío casi siempre en el manejo de la API directamente por la simpleza y poco peso final. El código que puse es parte del que desarrollé en el tema que bien conoces Treeview como explorer con checkboxes y pensé que la traducción del mismo podría arrojar simpleza, pero habiendo un componente original no tiene mucho sentido salvo para un desarrollo puntual sin la VCL.

Gracias por la información.

Saludos.

Neftali [Germán.Estévez] 01-06-2010 10:51:18

Cita:

Empezado por Faust (Mensaje 365760)
He descargado algunos componentes de torry y creo de delphi about, pero no me satisfacen, pues notifican p. ej. cuando se crea un archivo haciendo clic derecho en el explorador de windows clic en el submenu nuevo y archivo de texto, pero cuando algunos programas crean el archivo, p. ej. al darle guardar como, no lo notifica :mad:...

Pues si utiliza las API's no debería pasar, pues no debería influir quien crea el archivo para la notificación. :confused::confused::confused:

CHRISTIANHAZ77 01-06-2010 14:28:44

Muchas Gracias!
 
Agradezco a todos por la ayuda, es dificil iniciar preguntando algo, pero la verdad solucione lo que necesitaba, son casi los primeros pasos que doy en programacion, pero en un futuro no muy lejano seguro estare de su lado tambien colaborando. gracias


La franja horaria es GMT +2. Ahora son las 21:51:56.

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