Windows API for taskbar icon change for multiple monitors

bradyboyy88

Well-known Member
Joined
Feb 25, 2015
Messages
554
Hi,

I have the following code to update the icon in the taskbar for my userform below. It was great however, we have dual monitor setups and the primary monitor will show the correct icon in the task bar but all additional monitors have the usual excel icon. How can I switch all monitor taskbar icons for this?

Code:
Option Explicit
'--------------------------------Create Icons Variable Declarations (API Mainly)----------------------------------'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' modSetIcon
' This module contains code to change the icon of the Excel main
' window. The code is compatible with 64-bit Office.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=If"]#If[/URL]  VBA7 And Win64 Then
'''''''''''''''''''''''''''''
' 64 bit Excel
'''''''''''''''''''''''''''''
Private Declare PtrSafe Function SendMessageA Lib "user32" _
      (ByVal hWnd As LongPtr, _
      ByVal wMsg As LongPtr, _
      ByVal wParam As LongPtr, _
      ByVal lParam As LongPtr) As LongPtr


Private Declare PtrSafe Function ExtractIconA Lib "shell32.dll" _
      (ByVal hInst As LongPtr, _
      ByVal lpszExeFileName As String, _
      ByVal nIconIndex As LongPtr) As Long


Private Const ICON_SMALL = 0&
Private Const ICON_BIG = 1&
Private Const WM_SETICON = &H80


[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=Else"]#Else[/URL] 
'''''''''''''''''''''''''''''
' 32 bit Excel
'''''''''''''''''''''''''''''
Private Declare Function SendMessageA Lib "user32" _
      (ByVal hWnd As Long, _
        ByVal wMsg As Long, _
        ByVal wParam As Integer, _
      ByVal lParam As Long) As Long


Private Declare Function ExtractIconA Lib "shell32.dll" _
      (ByVal hInst As Long, _
      ByVal lpszExeFileName As String, _
      ByVal nIconIndex As Long) As Long


Private Const ICON_SMALL As Long = 0&
Private Const ICON_BIG As Long = 1&
Private Const WM_SETICON As Long = &H80
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=End"]#End[/URL]  If


'-------------Lightbox userform windowframe removal Variable Declariations (API Mainly)----------------------------'
'All Windows API variables that must be declared via module and not class module
'Hide userform window frames. Used in class module HideTitleBar
Public Const GWL_STYLE = -16
Public Const WS_CAPTION = &HC00000
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _
ByVal hWnd As Long, _
ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar Lib "user32" ( _
ByVal hWnd As Long) As Long
Public Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long


'------------------------------Open file API Calls--------------------------------------------'
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=If"]#If[/URL]  VBA7 And Win64 Then
Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" _
  Alias "ShellExecuteA" (ByVal hWnd As Long, _
  ByVal lpOperation As String, ByVal lpFile As String, _
  ByVal lpParameters As String, ByVal lpDirectory As String, _
  ByVal nShowCmd As Long) As Long
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=Else"]#Else[/URL] 
Private Declare Function ShellExecute Lib "shell32.dll" _
  Alias "ShellExecuteA" (ByVal hWnd As Long, _
  ByVal lpOperation As String, ByVal lpFile As String, _
  ByVal lpParameters As String, ByVal lpDirectory As String, _
  ByVal nShowCmd As Long) As Long
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=End"]#End[/URL]  If




'--------------------------------Create Icons--------------------------------------------------'
Sub SetIcon(FileName As String, Optional index As Long = 0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SetIcon
' This procedure sets the icon in the upper left corner of
' the main Excel window. FileName is the name of the file
' containing the icon. It may be an .ico file, an .exe file,
' or a .dll file. If it is an .ico file, Index must be 0
' or omitted. If it is an .exe or .dll file, Index is the
' 0-based index to the icon resource.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=If"]#If[/URL]  VBA7 And Win64 Then
    ' 64 bit Excel
    Dim hWnd As LongPtr
    Dim HIcon As LongPtr
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=Else"]#Else[/URL] 
    ' 32 bit Excel
    Dim hWnd As Long
    Dim HIcon As Long
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=End"]#End[/URL]  If
    Dim n As Long
    Dim S As String
    If Dir(FileName, vbNormal) = vbNullString Then
        ' file not found, get out
        Exit Sub
    End If
    ' get the extension of the file.
    n = InStrRev(FileName, ".")
    S = LCase(Mid(FileName, n + 1))
    ' ensure we have a valid file type
    Select Case S
        Case "exe", "ico", "dll"
            ' OK
        Case Else
            ' invalid file type
            Err.Raise 5
    End Select
    hWnd = Application.hWnd
    If hWnd = 0 Then
        Exit Sub
    End If
    HIcon = ExtractIconA(0, FileName, index)
    If HIcon <> 0 Then
        SendMessageA hWnd, WM_SETICON, ICON_SMALL, HIcon
    End If
End Sub
 
Last edited:

Some videos you may like

Excel Facts

Show numbers in thousands?
Use a custom number format of #,##0,K. Each comma after the final 0 will divide the displayed number by another thousand

bobsan42

Well-known Member
Joined
Jul 14, 2010
Messages
1,343
Well as far as I can tell the code works just fine (I will probably use it in the future with your permission) and it actually displays the selected icon on all taskbars.
However there is a system setting concerning the taskbar icons.
"Combine buttons on other taskbars" - to save space windows combines all buttons created by each application (even if it is only one) and only shows the application icon once.
To see separate buttons for each window set this to NEVER, or WHEN TASKBAR IS FULL. In this way your will see separate icon for each window.

Right click the taskbar and select Taskbar settings, scroll down to see the setting under Multiple displays (this is for Win 10).
 

bradyboyy88

Well-known Member
Joined
Feb 25, 2015
Messages
554
Hey Bob,

Yea feel free to use that code anytime! I have it set to never but it is still doing it. My issue is not when the task bar is full though. THe taskbar on the extended displays shows the excel icon and the primary display shows the correct logo. I am wondering if I am not understanding you correctly though.

Thanks.
 
Last edited:

bobsan42

Well-known Member
Joined
Jul 14, 2010
Messages
1,343
Make sure this is the setting for other taskbars and not for the main one.
I have only tested it on win10 pro 64bit.
Will send a screenshot tomorrow.
I hope you are not using some third party smart taskbar replacement?
 

bradyboyy88

Well-known Member
Joined
Feb 25, 2015
Messages
554
Sorry I forgot to reply back. You are absolutely right, looks like our work is using some sort of classic shell plugin. Ughhh now i have to get creative. Any ideas lol?
 

Watch MrExcel Video

Forum statistics

Threads
1,109,492
Messages
5,529,181
Members
409,856
Latest member
MAO
Top