Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Como actualizar el explorador (https://www.clubdelphi.com/foros/showthread.php?t=53620)

Negriz 25-02-2008 19:57:26

Como actualizar el explorador
 
Hola de nuevo mi pregunta es que si puedo hacer que mi aplicacion al salir (onClose event) refresque el explorer, es decir como si se presionara F5 o click derecho actualizar.

muchas gracias.

Lord Delfos 28-02-2008 02:38:14

Bueno, esto que voy a decir puede funcionar o no...

La cosa sería encontrar la ventana del explorador. Eso se hace con la función de la API llamada FindWindow.

Después uno le pasaría un mensaje con la función PostMessage pasándole la tecla F5 y el mensaje WM_KEYDOWN.

Todo esto suena muy lindo, pero el problema es encontrar la ventana con FindWindow. Esta función necesita saber, o bien el título de la ventana o la clase de la ventana. La primera es imposible de saber, y la segunda... bueno, también :(

Quizás tengas que explorar estos dos conceptos y ver qué pasa.

Saludos y suerte.

Negriz 03-03-2008 14:16:36

Cita:

Empezado por Lord Delfos (Mensaje 269249)
Bueno, esto que voy a decir puede funcionar o no...

La cosa sería encontrar la ventana del explorador. Eso se hace con la función de la API llamada FindWindow.

Después uno le pasaría un mensaje con la función PostMessage pasándole la tecla F5 y el mensaje WM_KEYDOWN.

Todo esto suena muy lindo, pero el problema es encontrar la ventana con FindWindow. Esta función necesita saber, o bien el título de la ventana o la clase de la ventana. La primera es imposible de saber, y la segunda... bueno, también :(

Quizás tengas que explorar estos dos conceptos y ver qué pasa.

Saludos y suerte.

Aclaro
pido disculpas por no haber formulado bien la pregunat, cuando me referia al explorador no queria decir "Internet explorer" o software similar....
solo pregunatava como hacer que se actaulizara "Mi Pc" por ejemplo o culaquier otra carpeta de windows.

muchas gracias "Lord Delfos" por tu respuesta y con respecto a la misma...

No me queda muy claro:

1) FindWindow se usa cuando no conozco la carpeta sierto... pero si ya se que carpeta es; por ejemlo la carpeta donde se esta ejecutando el programa o le solicito el directorio a la persona que usa el progrma... sirve? es decir le puedo dar estos datos a FindWindow. (Me podria dar la sitaxis).

2) la verdad no entiendo la forma de usar PostMessage.

muchas gracias por tu respuesta de verdad me ha sido de mucha ayuda...
por lo menos ya tengo por donde empezar...

Gracias

escafandra 03-03-2008 15:24:58

aquí tienes las respuestas:
http://msdn2.microsoft.com/en-us/library/ms633499.aspx
http://msdn2.microsoft.com/en-us/library/ms644944(VS.85).aspx

Saludos.

Negriz 05-03-2008 13:48:25

No me queda muy claro
 
He leido lo que me diste escafandra, pero no me queda muy claro como usarlo en c++ builder.

no es por que este en ingles, sino porque como no tengo un ejemplo ni la sintaxis adecuada para poder utilizarlo.

Alguno deustedes me podria ayudar con esto.

Muchas gracias por sus comentarios han sido de verdad de mucha ayuda.

Gracias.

escafandra 05-03-2008 17:52:06

Código:

char* Nombre_de_la_clase[] = "TApplication";  // o Nulo
char* Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar
HWND H = FindWindow(Nombre_de_la_clase, Nombre_de_ventana); // Handle de la ventana buscada

Revisa la ayuda del Builder para las API de Windows.

PostMessage es una API y tambien una función del propio Builder.
Revisa el concepto de mensage. Revisa en la ayuda de Builer los tipos de mensaje. Busca WM_.....

Saludos.

Negriz 10-03-2008 19:16:09

Muchas Gracias
 
Cita:

Empezado por escafandra (Mensaje 270894)
Código:

char* Nombre_de_la_clase[] = "TApplication";  // o Nulo
char* Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar
HWND H = FindWindow(Nombre_de_la_clase, Nombre_de_ventana); // Handle de la ventana buscada

Revisa la ayuda del Builder para las API de Windows.

PostMessage es una API y tambien una función del propio Builder.
Revisa el concepto de mensage. Revisa en la ayuda de Builer los tipos de mensaje. Busca WM_.....

Saludos.

gracias, perodona si me demore mucho en apreciar tu respuesta pero estuve un poco ocupado...

Muchas Gracias voy a provar.

Negriz 27-03-2008 17:11:25

disculpa escafandra, en la primera linea para que me sirve el nombre de la clase y que siginifica el ""TApplication";

char* Nombre_de_la_clase[] = "TApplication"; // o Nulo

gracias.

Antonioveneroso 27-03-2008 18:51:52

De la ayuda de C++ Builder:

Cita:

TApplication is the type used for a GUI windowed application.
TApplication is the type used for a GUI windowed application.

Unit
Forms

Description

TApplication encapsulates a windowed application. The methods and properties introduced in TApplication reflect the fundamentals established in the Windows operating system to create, run, sustain, and destroy an application. TApplication thereby simplifies the interface between the developer and the Windows environment. For this purpose, TApplication encapsulates behavior for

Windows message processing
Context-sensitive online help
Menu accelerator and key processing
Exception handling
Managing the fundamental parts defined by the Windows operating system for an application, such as MainWindow, WindowClass, and so on

Each GUI application automatically declares an Application variable as the instance of the application. If the C++Builder application is not a Web server application, control panel applet, or NT service application, this variable is of type TApplication.

TApplication does not appear on the Component palette, nor is it available in the form designer to visually manipulate; so it has no published properties. Nevertheless, some of its public properties can be set or modified at design time in the Forms and Application pages of the Project|Options dialog box. In addition, you can add a TApplicationEvents component to any form in the project to intercept the application’s events, and supply event handlers using the IDE.

Note: For application-wide properties and methods that affect the display, see TScreen.
Saludos!

escafandra 27-03-2008 19:06:41

Cita:

Empezado por Negriz (Mensaje 275650)
disculpa escafandra, en la primera linea para que me sirve el nombre de la clase y que siginifica el ""TApplication";

char* Nombre_de_la_clase[] = "TApplication"; // o Nulo

gracias.

TApplication es la clase Aplicación, encapsula tu aplicacion, como te muestra Antonioveneroso.

Para el uso de la API, necesitas el nombre de la clase en una cadena de caracteres, es decir "TApplication" que es un char*
Código:

char* Nombre_de_la_clase[] = "TApplication";
Por eso va entre "comillas".

Saludos.

Negriz 31-03-2008 22:47:45

Osea que:
HWND H = FindWindow(Nombre_de_la_clase, Nombre_de_ventana); // Handle de la ventana buscada
me almacena en la variavle HWND H la ventana que queria actualizar y ahora solo tengo que usar PostMessage... el problema es:

BOOL PostMessage( HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

lo que conozco es:
HWND hwnd, es la H en donde se guardo lo de FindWindow.
UINT Msg, es el mensage que quiero mostrar mos o msenos mi idea.
pero la verdad no tengo conocimiento de los datos que siguien...

Gracias por su ayuda, pido discupas por las molestias, pero una cosa mas...
que son esos datos de postmensage.

Gracias.
Saludos.

escafandra 31-03-2008 23:25:23

Para enviar el mensaje de presionar una tecla (F5):

Código:

PostMessage(H, WM_KEYDOWN, VK_F5, 1);  // Presionar
PostMessage(H, WM_KEYUP, VK_F5, 1);    // Soltar

Saludos.

Negriz 01-04-2008 18:55:38

entonces mi ocdigo terminaria asi:

char* Nombre_de_la_clase[] = "TApplication"; // o Nulo // esto no se cambia
char* Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar // ¿aqui puedo poner el ombre de la ventana si ya la conozoco?...
es decir, la ventana que deseo actualizar es donde esta el ejecutable.
//¿Pero pongo el nombre de la carpeta o la ruta a la carpeta?
//...continua el codigo
HWND H = FindWindow(Nombre_de_la_clase, Nombre_de_ventana); // Handle de la ventana buscada
//y luego le mando el mensage tal y como está? osea:
PostMessage(H, WM_KEYDOWN, VK_F5, 1); // Presionar
PostMessage(H, WM_KEYUP, VK_F5, 1); // Soltar

una ultima pregunta... ¿que bibliotecas tengo que declarar?

muchas gracias.

escafandra 03-04-2008 08:31:55

Código:

char* Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar
Significa lo que dice, no es el nombre del fichero ejecutable, sino el caption, el texto que aparece escrito encima de la ventana. Es el nombre por el que la reconoce esa API, y que tienes que conocer, de ahí la dificultad que plantea en diferentes máquinas. Por ejemplo, los caption pueden cambiar según el idioma...

Así que no tienes que poner ningún nombre de ruta....

Si tu código, donde usas esa API, esta definido en el archivo de un formulario, donde se definen los archivos.h para el uso de las VCL, entonces no tienes que incluir nada más, por defecto ya esta incluido. Si no es así:
Código:

#include <winuser.h>

Negriz 03-04-2008 16:49:07

Cita:

Empezado por escafandra (Mensaje 277221)
Código:

char* Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar
Significa lo que dice, no es el nombre del fichero ejecutable, sino el caption, el texto que aparece escrito encima de la ventana. Es el nombre por el que la reconoce esa API, y que tienes que conocer, de ahí la dificultad que plantea en diferentes máquinas. Por ejemplo, los caption pueden cambiar según el idioma...

Así que no tienes que poner ningún nombre de ruta....

aaa, gran problema y si le pido al usuario el nombre de su ventana?

mira, lo probe de la sigt manera:

Código:


void __fastcall TForm1::Button1Click(TObject *Sender)
{
char* Nombre_de_la_clase[] = "TApplication";  // o Nulo
char* Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar
HWND H = FindWindow(Nombre_de_la_clase, Nombre_de_ventana); // Handle de la ventana buscada.
PostMessage(K, WM_KEYDOWN, VK_F5, 1); // Presionar
PostMessage(K, WM_KEYUP, VK_F5, 1); // Soltar
}

pero me decia en la linea char* Nombre_de_la_clase[] = "TApplication"; // o Nulo me salia un error que decia "wanted (o algo asi: need o wait) *char got **char"; la idea es que esperaba algo y recivio otro.
y en la otra donde llamo FindWindow, me salia "no se puede convertir *char en **char"
pero luego lo puse asi:

Código:


void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString s = Application->ExeName;
AnsiString ExePath = ExtractFilePath(s);
char Nombre_de_la_clase[] = "TApplication";  // o Nulo//quito el *
HWND K = FindWindow( Nombre_de_la_clase, ExePath.c_str() );// Handle de la ventana buscada
PostMessage(K, WM_KEYDOWN, VK_F5, 1); // Presionar
PostMessage(K, WM_KEYUP, VK_F5, 1); // Soltar
}

y compila, pero cuando presiono el boton no pasa nada, y la ventan donde esta el ejecuable no se actualiza...
Aclaro que las modificaciones que hize no son basadas en experiencia, solo estaba probando:D.

Gracias por su ayuda.:)
saludos.:D

escafandra 04-04-2008 01:09:30

Tienes razón en una cosa, equivoqué una parte del código. Debe ser así:
Código:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char Nombre_de_la_clase[] = "TApplication";  // o Nulo
  char Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar
  HWND H = FindWindow(Nombre_de_la_clase, Nombre_de_ventana);// Handle de la ventana buscada.
  //Si falla (H == NULL), por lo que no tiene sentido seguir...
  if(H){
      ::SendMessage(H, WM_KEYDOWN, VK_F5, 1); // Presionar
      ::SendMessage(H, WM_KEYUP, VK_F5, 1); // Soltar
  }
}

El error estaba en definir un puntero a un puntero char* P[]. Cuando lo que quería definir es un puntero a una cadena, es decir o simplemente char* P ó char P[].

Sigues cometiendo el error de confundir el caption de la ventana con la ruta Path o el nombre del ejecutable.

Haz lo siguiente:

Abre una ventana del explorador, abre una carpeta (el caption puede variar al cambiar la carpeta visualizada) mira el caption y colocalo en tu código.

FindWindow te devuelve un HANDLE a esa ventana, si es nulo quiere decir que no la ha localizado, en caso contrario te vale, de forma que la simulación de presionar un botón esta condicionada a que el HANDLE no sea nulo.

Negriz 04-04-2008 18:51:05

hola, gracias por tu respuesta, mi pregunta es esta:
¿la caption de la ventana es el nombre de la carpeta?
si es asi:
¿no se supone que en la ruta esta el nombre de la carpeta?
¿y si saco solo el nombre de la carpteta de la ruta?¿funcionaria?

de todas manreas voy a prbar algunas cosas, dependiendo lo que pase lo posteo, muchas rgacias por ayudarme, no saben cuanto he aprendido con esta discusion,
muchas gracias.

saludos desde Colombia.

escafandra 04-04-2008 19:23:27

Pues es posible que en el explorador el Caption sea el nombre de la carpeta, el problema es que no puedes estar seguro de esto no va a cambiar de una maquina a otra o de un Sistema Operativo a otro (versiones nuevas de Windows), o con una opción de configuración nueva... Pero si estás seguro de que siempre va a corresponder el Caption del explorador con el nombre de la carpeta, pues adelante.

Otra cosa, no pongas Nombre_de_Clase "TApplication", eso es para aplicaiones delphi o builder, coloca en su lugar NULL:
Código:

HWND H = FindWindow(0, Nombre_de_ventana);
La mejor forma de experimentar con FindWindow es colocar el caption que tu veas en la ventana que quieres localizar.



Puedes experimentar también con otra API: WindowFromPoint. Te permite localizar la ventana que contiene un punto, que puede ser por ejemplo el cursor del ratón...

Código:

TPoint Point;
::GetCursorPos(&Point);
HWND h = WindowFromPoint(Point);

Saludos.

Negriz 04-04-2008 19:54:18

¿estamos hablando de la barra de titulo?
si es asi en windows he visto que en la caption hay dos posibilidades:
que solo se muestre el nombre de la carpeta o que se muestre toda la ruta en el titulo, si comparo is esta toda o solo la carpeta, es decir.

Cita:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
char Nombre_de_la_clase[] = "TApplication"; //se va con nulo
char Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar// aqui pongo el path de mi exe
HWND H = FindWindow(0, Nombre_de_ventana);// Handle de la ventana buscada.
//Si falla (H == NULL), por lo que no tiene sentido seguir...
if(H){
::SendMessage(H, WM_KEYDOWN, VK_F5, 1); // Presionar
::SendMessage(H, WM_KEYUP, VK_F5, 1); // Solta
else{
Nombre_de_ventana[] = "Nombre"; // Caption de la ventana a buscar// ahora pongo el nombre de la carpeta // cin strcpy
HWND H = FindWindow(0, Nombre_de_ventana);// Handle de la ventana buscada.
...bueno y compruebo y sigo

}
}
}
que tal, te parece que funcionaria.
El problema es que este no es mi PC y tengo que ver el code e ir a mi casa aprobar.
Saludos

keyboy 04-04-2008 20:05:00

Disculpen esta breve interrupción.

Me gustaría preguntarle a Negriz cuál es la necesidad de actualizar la ventana del explorador. Lo pregunto porque la API de Windows cuenta con la función ShChangeNotify, que hasta donde entiendo, sirve para notificar al shell acerca de cambios que una aplicación puede hacer que lo afecten. Eso incluye agregar o borrar archivos y directorios. Si la necesidad de actualizar la ventana del explorador viene de algo por este estilo, quizá le sea más conveniente usar la función referida y no depender así de cosas como el título de la ventana, que, como ya comentó escafandra, es poco fiable.

Bye

escafandra 04-04-2008 21:06:29

Pues la verdad, hacerlo como pretende es escabroso, pero yo creo que ya es una cuestión de curiosidad, a ver si le sale, más que por una cuestión práctica, y como él dice:
Cita:

Empezado por Negriz (Mensaje 277624)
de todas manreas voy a prbar algunas cosas, dependiendo lo que pase lo posteo, muchas rgacias por ayudarme, no saben cuanto he aprendido con esta discusion,
muchas gracias.

Negriz, prueba ese último código, puede funcionar, aunque no "al pié de la letra" según lo has citado. Experimenta. En una ocasión yo hice un programa para hacer una broma a un compañero de trabajo. Consistía en localizar cuando estaba jugando, para lo que utilizaba FindWindow y WindowFromPoint. Localizada la ventana del juego y conociendo que estaba en primer plano y con actividad (movimiento de ratón), esperaba 10 segundos y le minimizaba la ventana.....Fue divertido y aprendí mucho.

Negriz 07-04-2008 19:21:26

Cita:

Empezado por keyboy (Mensaje 277642)
Disculpen esta breve interrupción.

Me gustaría preguntarle a Negriz cuál es la necesidad de actualizar la ventana del explorador. Lo pregunto porque la API de Windows cuenta con la función ShChangeNotify, que hasta donde entiendo, sirve para notificar al shell acerca de cambios que una aplicación puede hacer que lo afecten. Eso incluye agregar o borrar archivos y directorios. Si la necesidad de actualizar la ventana del explorador viene de algo por este estilo, quizá le sea más conveniente usar la función referida y no depender así de cosas como el título de la ventana, que, como ya comentó escafandra, es poco fiable.

Bye

Lo que pasa es, supongamos que se hace un cambio en el desktop.ini de una carpeta para poner una imagen de fondo en ella; la idea es que apenas este cambio dse haga, dicha carpeta se actulize para que se vea la img.
Otro ejemplo es cuando cambias un icono con TuneUP o algun otro programa cuando aceptas los cambios, los iconos se refrescan.
algo asi mas o menos es lo que se desea hacer.

Cita:

Empezado por escafandra (Mensaje 277658)
Pues la verdad, hacerlo como pretende es escabroso, pero yo creo que ya es una cuestión de curiosidad, a ver si le sale, más que por una cuestión práctica.

En una ocasión yo hice un programa para hacer una broma a un compañero de trabajo. Consistía en localizar cuando estaba jugando, para lo que utilizaba FindWindow y WindowFromPoint. Localizada la ventana del juego y conociendo que estaba en primer plano y con actividad (movimiento de ratón), esperaba 10 segundos y le minimizaba la ventana.....Fue divertido y aprendí mucho.


Muchas gracias a todos por sus comentarios.
La verdad... eso es verdad, valga la redundancia.:D:D
yo quiero aprender y este tema me ha ayudad mucho.:eek::D

saludos desde colombia.:)

keyboy voy a mirar la funcion. gracias.

cHackAll 09-04-2008 00:23:49

Cita:

Empezado por Negriz (Mensaje 268507)
Hola de nuevo mi pregunta es que si puedo hacer que mi aplicacion al salir (onClose event) refresque el explorer, es decir como si se presionara F5 o click derecho actualizar.

muchas gracias.

Código:

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
 SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);
}

PD: solo para nutrir un poco el hilo :cool:

Saludos

Negriz 11-04-2008 16:09:40

Cita:

Empezado por cHackAll (Mensaje 278444)
Código:

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
 SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);
}

PD: solo para nutrir un poco el hilo :cool:

Saludos

Eso es lo que deseo hacer pero un poco mas especifico como haz podido leer, pero no es mala la idea, el codigo que colocaste funciona? porque la verdad no habia pensado en eso, cunado se cierre el programa que actualize.

cHackAll 14-04-2008 03:38:12

Cita:

Empezado por Negriz (Mensaje 279297)
...el codigo que colocaste funciona?

Dimelo tú ;)

Negriz 21-04-2008 02:28:14

Cita:

Empezado por cHackAll (Mensaje 279762)
Dimelo tú ;)

Si... Tienes razon...
aunque lo prbe pero lo probe y no se adapta a lo que neceisto...

ShChangeNotify... como es la sintaxis??? que pena pero mis conocimientos no son muy grandes...
Saludos y gracias.

cHackAll 21-04-2008 16:28:19

Si, también funciona;

Código:

SHSTDAPI_(void) SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2);
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 SHChangeNotify(0x8000000L/*SHCNE_ASSOCCHANGED*/, 0/*SHCNF_IDLIST*/, NULL, NULL);
}

ó

Código Delphi [-]
uses ShlObj;

procedure TForm1.Button1Click(Sender: TObject);
begin
 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;

Saludos

Negriz 30-04-2008 19:09:52

Cita:

Empezado por cHackAll (Mensaje 281436)
Si, también funciona;

Código:

SHSTDAPI_(void) SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2);
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 SHChangeNotify(0x8000000L/*SHCNE_ASSOCCHANGED*/, 0/*SHCNF_IDLIST*/, NULL, NULL);
}

ó

Código Delphi [-]
uses ShlObj;

procedure TForm1.Button1Click(Sender: TObject);
begin
 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;

Saludos

hola como estan...me disculpo por no haber dejado una respuesta en tanto tiempo.. pero es que estado un poco ocupado.

voy a probar.

Gracias

Negriz 07-05-2008 18:57:15

Nop, ya probe y no hace lo que esperaba.... aunque es muy util, ya que si cambio el autorun de la usb para darle un nuevo icono
esta funcion lo acutaliza (aveces) sin necesidad de sacarla y meterla de nuevo.

con respecto al explorer... no pasa nada.

no se si conocen el Desktop.ini
bueno un amigo me pidio que le hiziera algo donde el seleccionara la imagen y el programa le creara el desktop y le actualizara la imagen al salir....

ese es mi objetivo y por eso hize esta pregunta???

de todas maneras muchas gracias.... la verdad com dijo el amigo escafandra la verdad no esperaba averiguar tanto aca....

gracias.

Negriz 09-05-2008 21:44:55

Este es un exelente foro....
es uno de los emjores.

Grcias.

El Negriz.

Negriz 12-05-2008 19:30:58

hola...

Alguna otra sugerencia para actualizar el Desktop???

Grcias.

Negriz 26-05-2008 19:42:13

hola, gracias a todos por la ayuda.

he probado con la funcion SHChangeNotify... ahun si exito, pero creo que la solucion esta alli...

Gracias a todos...
Se acepatan sugerencias...

Saludos. El Negriz

escafandra 09-10-2008 21:52:07

Me gustaría resucitar este hilo para aportar un detalle útil en este tema, al menos para mi.

Código:

SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);
Que propuso cHackAll funciona muy bien, pero al actualizar el explorador, borra los ListView y los reescribe, con lo que el efecto visual de "apagón" o "parpadeo" no es muy elegante en máquinas lentas, aunque muy efectivo.

He traceado los mensajes del explorador y he visto dos cosas interesantes:
1º Al pulsar F5 se genera un mensaje WM_COMMAND LPARAM 0x1A220 LPARAM 0

2º Al elegir la opción de menú ver \ actualizar, se genera un mensaje WM_COMMAND LPARAM 0x0A220 LPARAM 0

Así que:
Código:

  PostMessage(HWND_BROADCAST, WM_COMMAND, 0x0A220, 0);
Actualiza inmediatamente el explorador de archivos sin parpadeo, como si lo hiciésemos desde menú o pulsando F5

La pega está en que este sistema es muy dependiente del software del explorador actual y si Microsoft lo cambia dejará de funcionar, así como no funcionará, muy posiblemente, en otros exploradores.

Como curiosidad, me ha parecido interesante publicarlo.

Saludos.

escafandra 10-10-2008 21:27:45

Bueno, he de hacer una aclaración a mi post anterior.

El sistema funciona tal cual, pero SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0); envía a "todas" las ventanas top-level. He comprobado que algunos elementos del Microsoft Office reaccionan mal a ese mensaje y se cuelgan.

Como la idea me sigue pareciendo buena, he creado un código para enviar el mensaje a todas las ventanas de una determinada clase (ClassName) con lo que el "bug" queda solucionado. Publico el código, considero que puede ser interesante para otras utilidades también.

Código:

// Estructura con los datos del mensaje a enviar y el nombre de la clase de ventana
struct TClassMsg{
  UINT  Msg;
  WPARAM wParam;
  LPARAM lParam;
  char*  ClassName;
};

BOOL CALLBACK EnumWindowsProc(HANDLE Handle, LPARAM lParam)
{
  int SizeBuffer = 256;
  char* Buffer = new char[SizeBuffer+1];
    TClassMsg *ClassMsg =  (TClassMsg*)lParam;
  int S = GetClassName(Handle, Buffer, SizeBuffer);
  if(S)
  if(stricmp(Buffer, ClassMsg->ClassName)==0){
      // Si coincide el ClasName con el deseado, se envía el mensaje
      PostMessage(Handle, ClassMsg->Msg, ClassMsg->wParam, ClassMsg->lParam);
  }

  delete Buffer;
  return true;
}

typedef BOOL (__stdcall *TP)();
void PostMessageToWindowClass(char *ClassName, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  TClassMsg ClassMsg;

  ClassMsg.Msg = Msg;
  ClassMsg.wParam = wParam;
  ClassMsg.lParam = lParam;
  ClassMsg.ClassName = ClassName;
 
  // Enumero las ventanas
  EnumWindows((TP)EnumWindowsProc, LPARAM(&ClassMsg));
}

Y para usarlo con los fines que propongo:
Código:

PostMessageToWindowClass("CabinetWClass", WM_COMMAND, 0x0A220, 0);
Por supuesto que puede ser mejorado y si alguien lo hace incluso lo agradezco.

Saludos.

Negriz 15-10-2008 17:49:49

pues la verdad si estab un poco muerto, voy a mirar gracias.

Negriz 07-11-2008 22:48:59

pues va de maravilla, muchas gracias...


La franja horaria es GMT +2. Ahora son las 12:19:58.

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