Mensaje    Asunto: Enviar mensaje a todas las ventanas de una Clase Registrada Responder citando

Se me planteó la pregunta de como actualizar el explorador de archivos desde una aplicación y alguien respondió con una sugerencia magistral

Código:
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);


Pero aunque tremendamente eficaz, el efecto visual en máquinas no muy rápidas produce un parpadeo poco estético. Pensé en simular la pulsación de F5 o la acción del menú \ ver \ actualizar. Tras realizar un traceo de los mensajes que le llegan al explorador de archivos, descubrí que:

F5 envía WM_COMMAND LPARAM 0x1A220 LPARAM 0
y el menú \ ver \ actualizar WM_COMMAND LPARAM 0x0A220 LPARAM 0

Así que, pensé que lo mejor era hacer: PostMessage(HWND_BROADCAST, WM_COMMAND, 0x0A220, 0); pero esto, al enviar "todas" las ventanas top-level el mensaje en cuestión, y siendo propio de una aplicación determinada, puede dar fallos en otras. Efectivamente, he comprobado que algunos elementos del Microsoft Office reaccionan mal a ese mensaje y se cuelgan.

Entonces pensé en escribir un código que envíe el MGS sólo a un determinado tipo de ventana (el explorador de archivos es "CabinetWClass"), y así evitar el error.

Publico, pues, el código sin extenderme más:

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 para decidir cuando envío el mensaje...
  EnumWindows((TP)EnumWindowsProc, LPARAM(&ClassMsg));
}


Y para resolver la pregunta inicial de como actualizar el explorador de archivos, sin parpadeo ni apagones poco estéticos:

Código:
PostMessageToWindowClass("CabinetWClass", WM_COMMAND, 0x0A220, 0);


Evidentemente la utilidad de este truco va mas allá de actualizar el explorador de archivos y cada uno sabrá darle el uso más oportuno.

Saludos.