Userform: Icon in Taskleiste anzeigen
#1
Liebe Leserin, lieber Leser,

manchmal besteht der Wunsch, dass eine Userform alleinig, also mit ausgeblendetem Excel auf dem Bildschirm angezeigt wird.
Schön wäre es dann auch, wenn in der Titlebar der Userform ein individuelles Icon angezeigt würde.
Hierzu gibt es sicher schon viele Beispiele im Netz.

Schwieriger wird es schon, wenn die Userform mit dem Icon auch in der Taskleiste angezeigt werden soll.
Als Childwindow der Excelanwendung wird die Userform wie alle anderen offenen Mappen nur unter dem Excel-Icon angezeigt.

Mit dem nachfolgenden Code-Beispiel kannst Du Deine Userform mit folgenden Eigenschaften ausstatten:
  • Minimierungsbutton in der Titelleiste zum Minimieren der Userform
  • Individuelles Icon in der Titelleiste der Userform
  • Alternativ: Komplettes Abschalten der Titelleiste
  • Icon der Userform in der Taskleiste als zusätzlicher Button incl. ToolTip
  • Userform immer im Vordergrund
  • Ausblenden des VBA-Editors während der Userformanzeige
  • Ausblenden des Excel-Icons in der Taskleiste

PS: Das Ein- und Ausblenden der Userform kann auch ohne Minimierungsbutton in der Titelleiste durch Klick auf das Taskleistenicon erfolgen.

Hinweis: Leider wird bei meiner XL-64-Version das Excel-Icon nicht entfernt, das erfolgt nur bei der XL-32-Version. Ist das bei anderen Nutzern auch so?

Dieser Code ist nur ein Beispiel. Damit der Code klein bleibt, wurde auf per Parameter einstellbare Alternativen verzichtet.
So ist es aber nach Codeanpassung u.a. natürlich möglich, das Icon aus einer ICO-, EXE- oder DLL-Datei zu holen oder die allwaysOnTop-Einstellung abzuschalten.

.xlsb   Userform_Icon_In_Taskleiste.xlsb (Größe: 37,24 KB / Downloads: 11)

Und nun viel Spaß und Erfolg damit.

Code:

Option Explicit

' UserForm-Icon in Taskleiste und Minimieren im Rahmen
#If Win64 Then
    Private Declare PtrSafe Function GetWindowLongA Lib "user32.dll" _
            Alias "GetWindowLongPtrA" ( _
            ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongA Lib "user32.dll" _
            Alias "SetWindowLongPtrA" ( _
            ByVal hWnd As LongPtr, ByVal nIndex As Long, _
            ByVal dwNewLong As LongPtr) As LongPtr
    Private Const ciFakt = 2
#Else
    Private Declare PtrSafe Function GetWindowLongA Lib "user32.dll" ( _
            ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongA Lib "user32.dll" ( _
            ByVal hWnd As LongPtr, ByVal nIndex As Long, _
            ByVal dwNewLong As LongPtr) As LongPtr
    Private Const ciFakt = 1
#End If

Private Const ciInitTab As Long = 12 * ciFakt
Private Const ciAddTab  As Long = 16 * ciFakt
Private Const ciActTab  As Long = 24 * ciFakt
Private Const ciDelTab  As Long = 20 * ciFakt
Private Const ciToolTip As Long = 76 * ciFakt
Private Const ciSetVal  As Long = 24 * ciFakt
Private Const ciCommit  As Long = 28 * ciFakt

Private Declare PtrSafe Function FindWindowA Lib "user32.dll" ( _
        ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function SendMessageA Lib "user32.dll" ( _
        ByVal hWnd As LongPtr, ByVal wMsg As Long, _
        ByVal wParam As LongPtr, ByVal lParam As Any) As LongPtr
Private Declare PtrSafe Function ShowWindow Lib "user32.dll" ( _
        ByVal hWnd As LongPtr, ByVal nCmdShow As Long) As Long
Private Declare PtrSafe Function SetWindowPos Lib "user32" ( _
        ByVal hWnd As LongPtr, ByVal hWndInsertAfter As LongPtr, _
        ByVal x As Long, ByVal y As Long, _
        ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function DispCallFunc Lib "oleAut32.dll" ( _
        ByVal pvInstance As LongPtr, ByVal offsetinVft As LongPtr, ByVal CallConv As Long, _
        ByVal retTYP As Integer, ByVal paCNT As Long, ByRef paTypes As Integer, _
        ByRef paValues As LongPtr, ByRef retVAR As Variant) As Long
Private Declare PtrSafe Function CoCreateInstance Lib "ole32" ( _
        ByRef rclsid As GUID, ByVal pUnkOuter As LongPtr, ByVal dwClsContext As Long, _
        ByRef riid As GUID, ByRef ppv As LongPtr) As Long
Private Declare PtrSafe Function CLSIDFromString Lib "ole32" ( _
        ByVal OleStringCLSID As LongPtr, ByRef cGUID As Any) As Long
Private Declare PtrSafe Function SHGetPropertyStoreForWindow Lib "Shell32.dll" ( _
        ByVal hWnd As LongPtr, ByRef riid As GUID, ByRef ppv As LongPtr) As Long

Private Type GUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4(0 To 7) As Byte
End Type
Dim tClsID As GUID, tIID As GUID

Private Type PROPERTYKEY
   fmtid As GUID
   pid   As Long
End Type
Dim tPK As PROPERTYKEY

Dim mhWndUF   As LongPtr, mhVBE As LongPtr                  ' Handle Userform und VBE-Editor
Dim lpBarList As LongPtr, lpStore As LongPtr
Dim mbVBE     As Boolean

Private Sub UserForm_Initialize()
  Const GWL_HWNDPARENT = (-8)
  Const GWL_STYLE = -16&
  Const WS_CAPTION = &HC00000                               ' <<<<< Nur für Caption weg >>>>>
  Const WS_MINIMAXIMIZEBOX = &H20000 '&H30000               ' WS_MINIMIZEBOX Or WS_MAXIMIZEBOX
  Const HWND_TOPMOST = -1                                   ' Userform allways on top
  Const WM_SETICON = &H80
  Dim hIcon As LongPtr
  
' <<<<< Hier Icon vorgeben oder mit LoadIcon aus Datei holen >>>>>
  hIcon = Image1.Picture.Handle                             ' Handle für Icon aus UF nehmen
' hIcon = Tabelle1.Image1.Picture.Handle                    ' Handle für Icon aus Sheet nehmen
  mhVBE = FindWindowA("wndclass_desked_gsk", vbNullString)  ' Handle des VBE-Editor holen
  mhWndUF = FindWindowA("ThunderDFrame", Caption)           ' Handle der Userform holen
  SetWindowLongA mhWndUF, GWL_STYLE, GetWindowLongA(mhWndUF, GWL_STYLE) _
                          Or WS_MINIMAXIMIZEBOX             ' Mini/Maxiboxen zufügen
' SetWindowLongA mhWndUF, GWL_STYLE, GetWindowLongA(mhWndUF, GWL_STYLE) _
                          And Not WS_CAPTION '              ' <<<<< Nur für Caption weg >>>>>
' DrawMenuBar mhWndUF                                       ' <<<<< Nur für Caption weg >>>>>
  SendMessageA mhWndUF, WM_SETICON, 0&, hIcon               ' Icon in Caption setzen
  SetWindowLongA mhWndUF, GWL_HWNDPARENT, 0                 ' Das Elternfenster der Userform entfernen
  SetWindowPos mhWndUF, HWND_TOPMOST, 0, 0, 0, 0, &H3       ' UF immer im Vordergrund <<<<< ggf. rausnehmen  >>>>>
  Application.Visible = False                               ' Excel anzeigen aus
  SetTaskBar "Dialogbox " & Caption & " wieder aktivieren"  ' <<<<< ToopTip ggf. anpassen >>>>>
End Sub

Private Sub SetTaskBar(Optional sToolTip As String)
' Teile von Jaafar Tribak verwendet
  Const IID_PropertyStore = "{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}"
  Const IID_PropertyKey = "{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}"
  Const CLSID_TASKLIST = "{56FDF344-FD6D-11D0-958A-006097C9A090}"
  Const IID_TASKLIST = "{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}"
  Const CLSCTX_INPROC_SERVER = &H1
  Const S_OK = 0
  
  Call CLSIDFromString(StrPtr(IID_PropertyStore), tIID)
  If SHGetPropertyStoreForWindow(mhWndUF, tIID, lpStore) = S_OK Then
      Call CLSIDFromString(StrPtr(IID_PropertyKey), tPK)
      #If Win64 Then
          Dim PV(2) As LongPtr
          PV(1) = StrPtr("Dummy")
      #Else
          Dim PV(3) As LongPtr
          PV(2) = StrPtr("Dummy")
      #End If
      tPK.pid = 5: PV(0) = 31
      SetTabList 0, ciSetVal, VarPtr(tPK), VarPtr(PV(0))    ' SetValue Methode
      SetTabList 0, ciCommit                                ' Commit Methode ggf. überflüssig

      Call CLSIDFromString(StrPtr(CLSID_TASKLIST), tClsID)
      Call CLSIDFromString(StrPtr(IID_TASKLIST), tIID)
      If CoCreateInstance(tClsID, 0, CLSCTX_INPROC_SERVER, tIID, lpBarList) = S_OK Then
         SetTabList 1, ciInitTab                            ' Tab initialisieren
         SetTabList 1, ciAddTab, mhWndUF                    ' Tab Userform zufügen
         SetTabList 1, ciActTab, mhWndUF                    ' Tab Userform aktivieren
         If Len(sToolTip) Then _
         SetTabList 1, ciToolTip, mhWndUF, StrPtr(sToolTip) ' ToolTip hinzufügen
' VBE-Editor ausblenden
         If IsWindowVisible(mhVBE) Then                     ' Nur wenn sichtbar
            ShowWindow mhVBE, 0 ' 0 = SW_HIDE               ' VBE-Editor ausblenden
            SetTabList 1, ciDelTab, mhVBE                   ' Tab VBE-Editor löschen
            mbVBE = True
         End If
         SetTabList 1, ciDelTab, Application.hWnd           ' Tab Excel-Application löschen
      End If
  End If
  
End Sub

Private Sub ResetTaskbar()
' Bereinigen der Taskleiste
  SetTabList 1, ciDelTab, mhWndUF                           ' Tab Userform löschen
  If mbVBE Then                                             ' (optional)
     SetTabList 1, ciAddTab, mhVBE                          ' Tab VBE-Editor zufügen
     ShowWindow mhVBE, 5  ' 5 = SW_SHOW                     ' VBE-Editor wieder anzeigen
  End If
  SetTabList 1, ciAddTab, Application.hWnd                  ' Tab Excel-Application zufügen
End Sub

Private Sub SetTabList(iPtArt As Integer, iTblOffs As Long, ParamArray vFuncParams() As Variant)
' Setzen der Taskleiste mit den gewünschten Elementen
' Teile von Jaafar Tribak verwendet
  Const CC_STDCALL = 4
  Dim vParamPtr()  As LongPtr, hInst As LongPtr
  Dim vParamType() As Integer
  Dim vRtn         As Variant
  Dim vParams()    As Variant
  Dim iMax As Long, i As Long
  
  vParams() = vFuncParams()
  iMax = Abs(UBound(vParams) - LBound(vParams) + 1&)
  If iMax = 0& Then
     ReDim vParamPtr(0 To 0)
     ReDim vParamType(0 To 0)
  Else
     ReDim vParamPtr(0 To iMax - 1&)
     ReDim vParamType(0 To iMax - 1&)
     For i = 0& To iMax - 1&
         vParamPtr(i) = VarPtr(vParams(i))
         vParamType(i) = VarType(vParams(i))
     Next i
  End If

  hInst = IIf(iPtArt = 1, lpBarList, lpStore)
  DispCallFunc hInst, iTblOffs, CC_STDCALL, vbLong, iMax, vParamType(0), vParamPtr(0), vRtn
End Sub


Private Sub UserForm_Terminate()
  ResetTaskbar
  Application.Visible = True
End Sub


' ----------- Userform beeenden ----------
Private Sub CommandButton1_Click()
  Unload Me
End Sub

_________
viele Grüße
Karl-Heinz
[-] Folgende(r) 1 Nutzer sagt Danke an volti für diesen Beitrag:
  • Mila
Antworten Top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste