Refrescar Escritorio de Windows y Explorador de Carpetas (solucionado)

Iniciado por okik, 10 Marzo 2015, 16:52 PM

0 Miembros y 1 Visitante están viendo este tema.

okik

Hola,
He buscado y rebuscado en la red y finalmente encontré la forma de refrescar el escritorio de windows y el Explorador de carpetas (Explorer)

Esto sirve para cuando cambias valores en el registro directamente desde tu programa, en lugar de usar Opciones de Carpeta. Por ejemplo, ocultar las extensiones de archivo, mostrar archivos ocultos o  mostrar vistas en miniaturas en lugar de iconos. Al refrescar automáticamente se muestran los cambios; si deshabilitas las extensiones de archivo, al refrescar (actualizar) se ocultan las extensiones.

Yo intuía que debía usar PostMessage o SendMessage, lo que no sabía era que comando usar. Finalmente los encontré pero referido a otros tipos de lenguaje, no para VB. He encontrado otras formas con VB pero no funcionaban o solamente funcionaban para el escritorio. Como explico más abajo, todo se tiene que hacer por separado: escritorio, explorador de windows y actualizar iconos.


Código completo y definitivo para refrescar el escritorio, el explorador de carpetas y ACTUALIZAR LOS ICONOS en XP/Vista/¿Windows 7/8?:

Código (vb) [Seleccionar]
Option Explicit
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long

Private Const WM_COMMAND = &H111
Private Const SC_REFRESH_DESKTOP = &H7103
Private Const SC_REFRESH_EXPLORER_VISTA = &HA220
Private Const SC_REFRESH_EXPLORER_XP = &H7FEF

'Función para actualizar los iconos
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" _
(ByVal hwnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long, _
ByVal fuFlags As Long, ByVal uTimeout As Long, _
lpdwResult As Long) As Long

Private Const WM_SETTINGCHANGE = &H1A
Private Const HWND_BROADCAST = &HFFFF&
Private Const SPI_SETNONCLIENTMETRICS = 42
Private Const SMTO_ABORTIFHUNG = &H2


Public Function RefreshDesktop()
Dim hwProgMan As Long, hwDesktop As Long, hwExplorer As Long

'Refresca el escritorio
hwProgMan = FindWindow("Progman", "Program Manager")
hwDesktop = FindWindowEx(hwProgMan, &H0, "SHELLDLL_DefView", vbNullString)
PostMessage hwDesktop, WM_COMMAND, SC_REFRESH_DESKTOP, &H0

'Refresca explorer
'VISTA/¿Windows 7/8?
hwExplorer = FindWindow("CabinetWClass", vbNullString)
PostMessage hwExplorer, WM_COMMAND, SC_REFRESH_EXPLORER_VISTA, &H0
'XP
hwExplorer = FindWindow("ExploreWClass", vbNullString)
PostMessage hwExplorer, WM_COMMAND, SC_REFRESH_EXPLORER_XP, &H0

'Actualiza los iconos
Call SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, &H0, SMTO_ABORTIFHUNG, &H1, &H0)
End Function

Private Sub Command1_Click()
RefreshDesktop
End Sub


'//////////////////
Tuve una errata ayer con el nombre de clase del explorador de windows para Windows XP; le añadí una R de más. La culpa es de google :¬¬ Como no estaba seguro busqué ahí y encontre referencias escrito así y bueno, esa es la escusa. Lo he corregido :D.

El nombre de clase de Explorer para XP es: "ExploreWClass". Con toda seguridad, lo he comprobado personalmente.

De todos modos el código o comando para refrescar Explorer en XP es diferente que en Vista o Windows 7. De modo que tampoco iba a funcionar aunque hubiera escrito bien el nombre de clase. Ayer comprobé cual era el comando a usar con spy++ y lo he añadido.

He añadido además el código para actualizar los iconos porque no se actualizaban los iconos. Esto es, cuando cambias el icono por defecto de una determinada extensión de archivo directamente en el registro de windows y quieres ver los cambios sin tener que cerrar sesión o simular un cambio en Opciones de carpeta.

No me extraña que no encontrara la forma de refrescar windows. Parece ser que hay que hacerlo todo por separado, por un lado el escritorio, por el otro Explorer y por el otro actualizar los iconos.


Como se puede ver, en XP el código wParam es &H7FEF=32751. Lo he testado y ¡funciona!.