none
¿Por casualidad no tienen un código que permita obtener el handle de los iconos del área de notificación que funcione en Windows 10 o Windows 8?

    Pregunta

  • Que haga uso de las funciones API o no, pero que me permita obtener el handle correspondiente a los íconos del área de notificación de Windows 10 u 8.

    He encontrado algunos códigos en la red pero son para Windows XP o en versiones antiguas de VB.NET y no logro hacerlos funcionar.

    Me refiero al Handle de estos botones.

    viernes, 11 de noviembre de 2016 4:12

Respuestas

  • Buscaba por la red una explicación que me ayude a ampliar el panorama pero no encontré mucho al respecto, por eso encuentro que estas respuestas que vienen de la experiencia resultan invaluables, la respuesta responde a las dudas que tenía, tengo al menos una base para seguir profundizando. Por otro lado la página proporcionada resulta de suma utilidad. Muchas gracias.

    ===================================================================================

    Si no es mucho pedir, aprovecho la oportunidad para pedirle ayuda con otra cosita aparte (aunque tiene que ver también con APIs), ojalá se pueda.

    Le explico: trato de obtener el Id. (Handle) de los íconos del área de notificación de Windows, tenía la idea que el área de notificación funciona como un contenedor y por tanto recorriendo sus elementos con la función FindWindowEx o con EnumWindows (si no me equivoco así se llaman las funciones) podría recorrer los íconos contenidos en este y así obtener el identificador de cada ícono, aunque de lo que he visto de cierta forma es así, no resulta tan sencillo como con otras ventanas.

    Probando varios códigos, pude obtener el Id. del área de notificación y la cantidad de íconos contenidos en este, hasta allí llegué.

    Buscando por la red di con varios códigos que hacen eso pero que no funcionan (no es que esten mal, sino que fueron hechos para el Visual Basic tradicional o para versiones antiguas de VB Net que funcionaban en su momento con Windows XP) y no he logrado que ninguno funcione en Windows 10 (Windows 10 pro para ser más preciso).

    No pretendo que me escriba todo el código, pero apelando a sus conocimientos a lo mejor Ud. logra hacer funcionar la parte del código que pongo en el enlace.

    De varios códigos que encontré, encuentro que el código siguiente está muy bien escrito, aunque el compilador no genera ningún error y corre, funciona hasta cierto punto pero no llega al objetivo final que es el de obtener información de cada ícono. Este es el procedimiento clave que no funciona:


    Private Shared Function GetButton(ByVal hProcess As SafeProcessHandle, ByVal index As Integer, _ 
                                          ByVal hwndTrayToolbar As IntPtr) As TrayButton 
            Dim tbb As New TBBUTTON 
            Dim friendlyTB As New TrayButton 
            friendlyTB.SetTrayIndex(index) 
            Dim pButton As IntPtr = IntPtr.Zero 
            Try 
                ' Create memory in the explorer process to store a TBBUTTON strucutre: 
                pButton = VirtualAllocEx(hProcess, Nothing, tbb.Size, MEM_COMMIT, PAGE_READWRITE) 
                ' Use SendMessage to request that the memory is filled with the TBBUTTON @ index. 
                Dim bResult As Boolean = SendMessage(hwndTrayToolbar, TB_GETBUTTON, index, pButton) 
                If bResult = False Then Throw New Win32Exception 
                ' And read the memory from the other process: 
                Dim bytesReturned As Integer 
                bResult = ReadProcessMemory(hProcess, pButton, tbb, tbb.Size, bytesReturned) 
                If bResult = False Then Throw New Win32Exception 
                ' Now we need to get the NOTIFYICONDATA-sorta structure: 
                Dim nid As New NotifyIconData 
                ' It lives at the memory pointed to by tbb.data, again it is in the other process: 
                bResult = ReadProcessMemory(hProcess, tbb.data, nid, nid.Size, bytesReturned) 
                If bResult = False Then Throw New Win32Exception 
                ' And we can grab the string too, though it might not work for all icons as some store an index: 
                Dim sb As New StringBuilder(1024) 
                bResult = ReadProcessMemory(hProcess, tbb.iString, sb, sb.Capacity, bytesReturned) 
                If bResult = False Then Throw New Win32Exception 
                friendlyTB.SetText(sb.ToString) 
                ' Next we can get the process id, from the buttons hwnd: 
                Dim id As UInteger 
                GetWindowThreadProcessId(nid.hWnd, id) 
                friendlyTB.SetPid(id) 
                ' And another api to get the image file name from the process id: 
                friendlyTB.SetProcessPath(FilenameFromPid(id)) 
                ' For the icon, see if one exists first.             
                Dim iconInfo As New ICONINFO 
                bResult = GetIconInfo(nid.hIcon, iconInfo) 
                Try 
                    If bResult Then 
                        Dim icon As Icon = icon.FromHandle(nid.hIcon) 
                        friendlyTB.SetIcon(icon) 
                    Else 
                        ' These are invalid icon handles. The icons are using a different technique 
                        ' - sending windows messages to the tray to get it to update the icons. 
                    End If 
                Finally 
                    ' prevent memory leaks - we need to clean up the handles inside the ICONINFO structure. 
                    If iconInfo.hbmColor <> IntPtr.Zero Then 
                        DeleteObject(iconInfo.hbmColor).ToString() 
                    End If 
                    If iconInfo.hbmMask <> IntPtr.Zero Then 
                        DeleteObject(iconInfo.hbmMask).ToString() 
                    End If 
                End Try 
            Finally 
                If pButton <> IntPtr.Zero Then 
                    Dim freeResult As Boolean = VirtualFreeEx(hProcess, pButton, 0, MEM_RELEASE) 
                    If freeResult = False Then Throw New Win32Exception 
                End If 
            End Try 
                Return friendlyTB 
        End Function 

    El código completo lo puede descargar desde aquí (El archivo se llama GetTheTray.zip):

    https://onedrive.live.com/?id=862DEE3EC267CB5C%21146&cid=862DEE3EC267CB5C

    ---------------------------------------------------------------

    Aquí hay dos códigos más de otras fuentes que hacen lo mismo (pero tampoco funcionan en Windows 10)

    los pongo por si acaso sirvan:

    http://www.xiaozhou.net/vb-enumeration-tray-icon-2005-12-08.html

    http://www.codeproject.com/Articles/10807/Shell-Tray-Info-Arrange-your-system-tray-icons

    -----------------------------------------------------------------

    Cualquiera sea la respuesta, muchas gracias de antemano.

    martes, 15 de noviembre de 2016 5:50