GetWndIcon


Description:
This is a simple wrapper function that attempts to use WM_GETICON and GetClassLong to return an icon for a specified window. It takes two parameters, a handle to the window in question, and a boolean specifying whether to grab the small or large icon. It returns the icon, or 0 if it can't load the icon.
 
Code:
Option Explicit

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
Declare Function GetClassLong Lib "user32" Alias "GetClassLongA" (ByVal _
        hwnd As Long, ByVal nIndex As Long) As Long

Const GCL_HICON = (-14)
Const GCL_HICONSM = (-34)
Const WM_GETICON = &H7F
Const WM_SETICON = &H80
Const ICON_SMALL = 0
Const ICON_BIG = 1


Public Function GetWndIcon(hWndIcon As Long, bLarge As Boolean) As Long
    'Attempts to grab the icon for a window
    
    ' First off, attempt WM_GETICON, use SendMesageTimeout so we don't
    '  hang on windows that aren't responding
    SendMessageTimeout hWndIcon, WM_GETICON, IIf(bLarge, ICON_BIG, _
                       ICON_SMALL), 0, 0, 1000, GetWndIcon
                
    If GetWndIcon = 0 Then
        ' If WM_GETICON didn't return anything, try using
        '  GetClassLong to get the icon for the window's class
        GetWndIcon = GetClassLong(hWndIcon, IIf(bLarge, GCL_HICON, _
                   GCL_HICONSM))
    End If
    
End Function

 
Sample Usage:
 
    Dim hIconReturn As Long
    Dim hWndIcon As Long
    
    hWndIcon = FindWindow(vbNullString, "Untitled - Notepad")
    
    hIconReturn = GetWndIcon(hWndIcon, True)
    DrawIconEx Me.hdc, 0, 0, hIconReturn, 32, 32, 0, 0, DI_NORMAL
    DeleteObject hIconReturn
    
    hIconReturn = GetWndIcon(hWndIcon, False)
    DrawIconEx Me.hdc, 32, 16, hIconReturn, 16, 16, 0, 0, DI_NORMAL
    DeleteObject hIconReturn