escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Vie 10 Oct, 2008 11:11 pm Asunto: Enviar mensaje a todas las ventanas de una Clase Registrada |
|
|
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. |
|