Anzeige
Archiv - Navigation
1900to1904
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Userform in Taskleiste

Userform in Taskleiste
22.09.2022 05:59:00
Thomas
Hallo zusammen,
bezugnehmend auf diesen Thread https://www.herber.de/forum/archiv/1896to1900/1898854_Userform_in_Taskleiste.html#1899622
@Karl-Heinz und @Nepumuk, das minimieren funktioniert grundsätzlich einwandfrei und das nicht das Userform Icon in der Taskleiste angezeigt wird, da kann ich mit leben, was aber ketzt nicht so gut ist das wenn das Userform minimiert wird in der Taskleiste gar kein Icon angezeigt wird, weder Excel noch das Userform, ich kann dann zur Userform nur über Alt+Umschalt zurückkehren.
Der Code sieht jetzt so aus, nach Karl-Heinz letztem Beispiel Code (SetWindowPos hab ich rausgenommen, da das UserForm nicht immer im Vordergrund sein soll.)

'UserForm in Taskleisten und Minimieren im Rahmen
Private Declare PtrSafe Function FindWindowA Lib "user32.dll" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#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 Declare PtrSafe Function SetClassLongA Lib "user32" _
Alias "SetClassLongPtrA" ( _
ByVal Hwnd As LongPtr, ByVal nIndex As Long, _
ByVal dwNewLong As LongPtr) As LongPtr
#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 Declare PtrSafe Function SetClassLongA Lib "user32" ( _
ByVal Hwnd As LongPtr, ByVal nIndex As Long, _
ByVal dwNewLong As LongPtr) As LongPtr
#End If
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 ShowWindow Lib "user32.dll" ( _
ByVal Hwnd As LongPtr, _
ByVal nCmdShow As Long) As Long
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 Const WM_SETICON As Long = &H80
Private Const GC_CLASSNAMEUSERFORM As String = "ThunderDFrame"
Private Const GWL_EXSTYLE As Long = -20
Private Const WS_EX_APPWINDOW As LongPtr = &H40000
Private Const SW_HIDE As Long = 0
Private Const SW_SHOW As Long = 5
Private mlngptrHwnd As LongPtr
'Userform Minimieren
Private Sub mupHauptFenster_Change()
End Sub
Private Sub UserForm_Activate()
ThisWorkbook.Activate
Dim lngptrStyle As LongPtr
Call ShowWindow(Hwnd, SW_HIDE)
lngptrStyle = GetWindowLongA(Hwnd, GWL_EXSTYLE)
lngptrStyle = lngptrStyle Or WS_EX_APPWINDOW
Call SetWindowLongA(Hwnd, GWL_EXSTYLE, lngptrStyle)
Call ShowWindow(Hwnd, SW_SHOW)
End Sub
Private Property Get Hwnd() As LongPtr
Hwnd = mlngptrHwnd
End Property
Private Property Let Hwnd(ByVal pvlngptrHwnd As LongPtr)
mlngptrHwnd = pvlngptrHwnd
End Property
Private Sub UserForm_Initialize()
'Minimieren funktion im Userform
Dim Hwnd As LongPtr
Const GCL_HICON = (-14)
Const GWL_STYLE = -16&
Const WS_MINIMAXIMIZEBOX = &H30000
Const HWND_TOPMOST = -1
' Mini/Maximieren-Funktion im Userform
Hwnd = FindWindowA("ThunderDFrame", Caption)          ' Handle Userform holen
SetWindowLongA Hwnd, GWL_STYLE, GetWindowLongA(Hwnd, GWL_STYLE) _
Or WS_MINIMAXIMIZEBOX            ' Mini/Maxiboxen zufügen
End Sub
Danke

17
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Userform in Taskleiste
22.09.2022 08:10:55
volti
Hallo Thomas,
bei dieser (meiner) Code-Version bleibt bei mir nach Minimierung der Userform das Userform/Icon-Bild in der Taskleiste erhalten und die UF kann wieder reaktiviert werden.
Ich nutze Excel 365.
Code:


Option Explicit ' UserForm in Taskleisten und Minimieren im Rahmen Private Declare PtrSafe Function FindWindowA Lib "user32.dll" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr #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 #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 #End If 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 Dim mhWnd As LongPtr Private Sub UserForm_Initialize() Const GWL_STYLE = -16& Const WS_MINIMAXIMIZEBOX = &H30000 Const WM_SETICON = &H80 mhWnd = FindWindowA("ThunderDFrame", Caption) ' Handle Userform holen SetWindowLongA mhWnd, GWL_STYLE, GetWindowLongA(mhWnd, GWL_STYLE) _ Or WS_MINIMAXIMIZEBOX ' Mini/Maxiboxen zufügen SendMessageA mhWnd, WM_SETICON, 0&, Image1.Picture.Handle ' Icon in Caption setzen Application.Visible = False ' Excel anzeigen aus End Sub Private Sub Userform_Activate() Const GWL_EXSTYLE = -20 Const WS_EX_APPWINDOW = &H40000 ShowWindow mhWnd, 0 ' 0 = SW_HIDE SetWindowLongA mhWnd, GWL_EXSTYLE, GetWindowLongA(mhWnd, GWL_EXSTYLE) _ Or WS_EX_APPWINDOW ' Fensterstyle ändern ShowWindow mhWnd, 5 ' 5 = SW_SHOW End Sub Private Sub CommandButton1_Click() Call Unload(Object:=Me) Application.Visible = True End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz

Anzeige
AW: Userform in Taskleiste
22.09.2022 13:09:41
JoWE
Hallo,
interessante Sache: Kannst Du bitte eine Arbeitsmappe hochladen, die den gesamten notwendigen Code enthält?
Grß
Jochen
AW: Userform in Taskleiste
22.09.2022 15:08:37
JoWE
Danke Dir
natürlich geht mein Dank auch an Nepumuk
LG
Jochen
AW: Userform in Taskleiste
26.09.2022 05:08:37
Thomas
Hi Karl-Heinz, hast recht, dein Code funktioniert ohne Probleme, da hatte ich mir wohl irgendwo einen Bock eingebaut. Hab es jetzt von dir komplett übernommen und dann klappt es auch, bis auf das Userform Icon, das ist weiterhin nur das Excel Icon, aber damit kann/muss ich dann leben.
Danke für deine Unterstützung.
Anzeige
AW: Userform in Taskleiste
23.09.2022 23:45:09
volti
Hallo zusammen,
geht nicht, gibt's nicht.
Mit nachfolgendem Code (in Gänze auch in der anliegenden Datei) lässt sich das Userform-Icon nun doch auch in der Taskleiste darstellen.
Alternativ kann man den VBE-Editor und weitere Exceldateien in der Taskleiste auch ausblenden.
PS: Das Thema ist nicht einfach. So kommt trotz Komprimierung des Codes noch einiges an zusätzlichem Code dazu.
UserformIcon_In_Taskleiste.xlsb
Code:


Option Explicit ' UserForm-Icon in Taskleiste und Minimieren im Rahmen Private Declare PtrSafe Function FindWindowA Lib "user32.dll" ( _ ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr #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 #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 #End If 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 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 Const ciInitTab As Long = 24 Private Const ciAddTab As Long = 32 Private Const ciActTab As Long = 48 Private Const ciDelTab As Long = 40 Private Const ciToolTip As Long = 152 Private Const ciSetVal As Long = 48 Private Const ciCommit As Long = 56 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 mhWnd As LongPtr, mhVBE As LongPtr ' Handle Userform, VBE-Editor Dim pTBarList As LongPtr, pPstore As LongPtr Dim PV(0 To 2) As LongPtr Private Sub UserForm_Initialize() Const GWL_STYLE = -16& Const WS_MINIMAXIMIZEBOX = &H20000 '&H30000 ' WS_MINIMIZEBOX Or WS_MAXIMIZEBOX Const HWND_TOPMOST = -1 Const WM_SETICON = &H80 mhVBE = FindWindowA("wndclass_desked_gsk", vbNullString) ' Handle des VBE-Editor holen mhWnd = FindWindowA("ThunderDFrame", Caption) ' Handle der Userform holen SetWindowLongA mhWnd, GWL_STYLE, GetWindowLongA(mhWnd, GWL_STYLE) _ Or WS_MINIMAXIMIZEBOX ' Mini/Maxiboxen zufügen SendMessageA mhWnd, WM_SETICON, 0&, Image1.Picture.Handle ' Icon aus UF in Caption setzen ' SendMessageA mhWnd, WM_SETICON, 0&, Tabelle1.Image1.Picture.Handle _ ' Icon aus Sheet in Caption setzen Application.Visible = False ' Excel anzeigen aus End Sub Private Sub UserForm_Activate() Const GWL_HWNDPARENT = (-8) SetWindowLongA mhWnd, GWL_HWNDPARENT, 0 ' Das Elternfenster der Userform entfernen SetTaskBar UserForm1, "Dialogbox aktivieren" End Sub Private Sub SetTaskBar(ByVal Form As Object, Optional sToolTip As String) PV(0) = 31: PV(1) = StrPtr("Dummy") 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 Call CLSIDFromString(StrPtr(IID_PropertyStore), tIID) If SHGetPropertyStoreForWindow(mhWnd, tIID, pPstore) = 0 Then Call CLSIDFromString(StrPtr(IID_PropertyKey), tPK) tPK.pid = 5 SetTabList 0, ciSetVal, VarPtr(tPK), VarPtr(PV(0)) ' SetValue Methode SetTabList 0, ciCommit ' Commit Methode Call CLSIDFromString(StrPtr(CLSID_TASKLIST), tClsID) Call CLSIDFromString(StrPtr(IID_TASKLIST), tIID) If CoCreateInstance(tClsID, 0, CLSCTX_INPROC_SERVER, tIID, pTBarList) = 0 Then SetTabList 1, ciInitTab ' Tab initialisieren SetTabList 1, ciDelTab, mhWnd ' Tab Userform löschen SetTabList 1, ciAddTab, mhWnd ' Tab Userform zufügen SetTabList 1, ciActTab, mhWnd ' Tab Userform aktivieren If Len(sToolTip) Then SetTabList 1, ciToolTip, mhWnd, StrPtr(sToolTip) ' ActivateTab Method End If ' VBE-Editor ausblenden SetTabList 1, ciDelTab, Application.hWnd ' Tab Excel-Application löschen If IsWindowVisible(mhVBE) Then ' Nur wenn sichtbar ShowWindow mhVBE, 0 ' VBE-Editor ausblenden SetTabList 1, ciDelTab, mhVBE ' Tab VBE-Editor löschen End If End If End If End Sub Private Sub ResetTaskbar() ' Bereinigen der Taskleiste SetTabList 1, ciDelTab, mhWnd ' Tab Userform löschen SetTabList 1, ciAddTab, mhVBE ' Tab VBE-Editor zufügen (optional) 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 geüwnschten Elementen 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 End If hInst = IIf(iPtArt = 1, pTBarList, pPstore) DispCallFunc hInst, iTblOffs, CC_STDCALL, vbLong, iMax, vParamType(0), vParamPtr(0), vRtn End Sub ' ----------- Userform beeenden ---------- Private Sub CommandButton1_Click() ResetTaskbar Unload Me Application.Visible = True End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz

Anzeige
AW: Userform in Taskleiste
26.09.2022 05:16:18
Thomas
Ich bin tief beeindruckt, versteh zwar kaum was was der Code macht, aber es funktioniert, absolut einwandfrei. !!!
An der stelle muss ich dann nochmal fragen, wie/wo lernt man das bzw. kann man das lernen? Welche Bücher sind zu empfehlen? Würde mich da gerne mal mehr mit beschäftigen.
Danke für deinen Code hier!
AW: Userform in Taskleiste
26.09.2022 05:40:05
Thomas
Hallo nochmal, jetzt hab ich mal ein bisschen getestet und mir ist ein neues Verhalten aufgefallen was ich so vorher nicht hatte. Wenn das Userform aktiv ist dann ist die Excel Mappe ausgeblendet, so das man nur das Userform sieht (Application.Visible=False), das war auch immer so wenn ich dann noch eine andere Exceldatei geöffnet habe, dann war diese Datei und das Userform zu sehen, aber nicht die Exceldatei "hinter" dem Userform.
Jetzt ist es so das wenn ich die zweite Exceldatei öffne dann auch die Tabellen hinter dem Userform mit eingeblendet werden und zu sehen sind, das sollte so nicht sein, ich hab schon an verschiedenen stellen versucht über ein Application.Visible = False das zu verhindern, nur leider ohne erfolg....
Vielleicht hast du dafür auch noch eine idee.
Anzeige
AW: Userform in Taskleiste
26.09.2022 08:28:27
volti
Hallo Thomas,
meine "Weisheiten" zur Windows-API habe ich schon seit den 90er Jahren aus den Büchern "Programming Windows 3.1" bzw. "Programming Windows 95" von Charles Petzold (Microsoft Press). Allerdings hatte ich damals nicht VBA programmiert, sondern Programme unter PowerBasic erstellt. Das Buch ist in englisch geschrieben. Die Beispiele sind für C, aber das ist kein Problem.
Andere Bücher kenne ich nicht, da ich jetzt seit mehr als zehn Jahren nur noch im Internet recherchiere. Mittlerweile gibt es ja auch 64-Bit.
Für VBA müssen auch andere Datentypen verwendet werden.
Functions und Subs sowie Konstanten und Types kannst Du auch hier in meinem API-Viewer finden.
Eine angepasste Version meines Codes zu Deinem Thema findest Du auch hier. Hier gibt es auch noch einige Erklärungen zum Code und notwendige Anpassungen bzgl. 32-Bit-Office. Ich habe hier 64Bit-Office.
Zu Deiner Frage bzgl. der Anzeige bei mehreren Exceldateien usw. muss ich im Laufe des Tages selbst erst mal testen, da ich mir dieses Thema auch gerade erst erschlossen habe.
Ggf. auch mal mit "SetTabList 1, ciDelTab, Application.hWnd ' Tab Excel-Application löschen" spielen.
Gruß
Karl-Heinz
Anzeige
AW: Userform in Taskleiste
26.09.2022 12:13:18
volti
Hallo Thomas,
ggf. die ursprüngliche "WS_EX_APPWINDOW"-Version wieder reinsetzen.
Das Handle einer Mappe ermitteln ist mir jetzt zu aufwändig und ob es überhaupt klappen würde, weiß ich nicht. Ansonsten habe ich jetzt erst mal keine weitere Idee dazu.
Code:


Private Sub UserForm_Activate() Const GWL_HWNDPARENT = (-8) Const GWL_EXSTYLE = -20 Const WS_EX_APPWINDOW = &H40000 ShowWindow mhWnd, 0 ' 0 = SW_HIDE ' UF anzeigen ein SetWindowLongA mhWnd, GWL_EXSTYLE, GetWindowLongA(mhWnd, GWL_EXSTYLE) _ Or WS_EX_APPWINDOW ' Fensterstyle ändern ShowWindow mhWnd, 5 ' 5 = SW_SHOW ' UF anzeigen ein SetWindowLongA mhWnd, GWL_HWNDPARENT, 0 ' Elternfenster der UF entfernen SetTaskBar UserForm1, "Dialogbox aktivieren" End Sub

_________________________
viele Grüße aus Freigericht 😊
Karl-Heinz

Anzeige
AW: Userform in Taskleiste
27.09.2022 05:16:55
Thomas
Hallo Karl-Heinz, nein leider hilft das nicht bzw. führt dazu das dann auch das Icon wieder nicht mehr in der Taskleiste angezeigt wird.
Wenn ich das sich öffnende Excel Fenster dann einmal minimiere ist es wieder komplett ausgeblendet und wird erst wieder sichtbar wenn ich noch eine Arbeitsmappe öffne....
AW: Userform in Taskleiste
27.09.2022 05:26:55
Thomas
Mir ist grade leider noch ein Nebeneffekt aufgefallen, @Nepumuk hatte mir mal eine Prozedur zur verfügunggestellt mit der man mit dem Scrollrad der Maus in der Userform scrollen konnte, das klappt nun leider nicht mehr. Der Aufruf der Prozedur klappt noch aber das Mausrad funktioniert dann nicht. Da scheint sich jetzt irgendwas in die Quere zu kommen.

'Modul um die Windows Api zu nutzen dmait das Mausrad in dem UserForm genutzt werden kann, hier für die 64 Bit  Version
Option Explicit
Option Private Module
#If Win64 Then
Private Declare PtrSafe Function GetWindowLongPtrA Lib "user32.dll" ( _
ByVal hWnd As LongPtr, _
ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function WindowFromPoint Lib "user32.dll" ( _
ByVal point As LongLong) As LongPtr
Private Declare PtrSafe Function SetWindowsHookExA Lib "user32.dll" ( _
ByVal idHook As Long, _
ByVal lpfn As LongPtr, _
ByVal hmod As LongPtr, _
ByVal dwThreadId As Long) As LongPtr
Private Declare PtrSafe Function CallNextHookEx Lib "user32.dll" ( _
ByVal hHook As LongPtr, _
ByVal ncode As Long, _
ByVal wParam As LongPtr, _
ByRef lParam As Any) As LongPtr
Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32.dll" ( _
ByVal hHook As LongPtr) As Long
Private Declare PtrSafe Function GetCursorPos Lib "user32.dll" ( _
ByRef lpPoint As POINTAPI) As Long
Private Declare PtrSafe Function GetKeyState Lib "user32.dll" ( _
ByVal nVirtKey As Long) As Integer
Private Declare PtrSafe Function PostMessageA Lib "user32.dll" ( _
ByVal hWnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As Long
Private Declare PtrSafe Function FindWindowA Lib "user32.dll" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr
Private Type POINTAPI
XY As LongLong
End Type
Private Type MOUSEHOOKSTRUCT
pt As POINTAPI
hWnd As LongPtr
wHitTestCode As Long
dwExtraInfo As LongPtr
End Type
Private Const WH_MOUSE_LL As Long = 14&
Private Const WM_MOUSEWHEEL As LongPtr = &H20A
Private Const HC_ACTION As Long = 0&
Private Const GWL_HINSTANCE As Long = -6&
Private Const WM_KEYDOWN As Long = &H100
Private Const SCROLL_DOWN As LongPtr = &H780000
Private Const GC_CLASSNAMEUSERFORM As String = "ThunderDFrame"
Private llngptrMouseHook As LongPtr
Private llngptrControlHwnd As LongPtr
Private llngPage As Long
Private lblnHook As Boolean
Private lobjScrollObject As Object
Public Sub HookMouse64(ByRef probjUserform As Object, ByRef probjScrollObject As Object, Optional ByVal opvlngPage As Long)
Dim lngptrHinstance As LongPtr
Dim lngptrFormHwnd As LongPtr
Dim lngptrHwndUnderCursor As LongPtr
Dim udtPoint As POINTAPI
llngPage = opvlngPage
Call GetCursorPos(udtPoint)
lngptrHwndUnderCursor = WindowFromPoint(udtPoint.XY)
If llngptrControlHwnd  lngptrHwndUnderCursor Then
Call UnhookMouse64
Set lobjScrollObject = probjScrollObject
llngptrControlHwnd = lngptrHwndUnderCursor
lngptrFormHwnd = FindWindowA(GC_CLASSNAMEUSERFORM, probjUserform.Caption)
lngptrHinstance = GetWindowLongPtrA(lngptrFormHwnd, GWL_HINSTANCE)
If Not lblnHook Then
llngptrMouseHook = SetWindowsHookExA(WH_MOUSE_LL, AddressOf MouseProc, lngptrHinstance, 0&)
lblnHook = llngptrMouseHook  0
End If
End If
End Sub
Public Sub UnhookMouse64()
If lblnHook Then
Call UnhookWindowsHookEx(llngptrMouseHook)
Set lobjScrollObject = Nothing
llngptrMouseHook = 0
llngptrControlHwnd = 0
lblnHook = False
End If
End Sub
Private Function MouseProc(ByVal pvlngCode As Long, ByVal pvlngptrParam As LongPtr, ByRef prudtParam As MOUSEHOOKSTRUCT) As LongPtr
Dim lngptrHwndUnderCursor As LongPtr
On Error GoTo err_exit
If pvlngCode = HC_ACTION Then
lngptrHwndUnderCursor = WindowFromPoint(prudtParam.pt.XY)
If lngptrHwndUnderCursor = llngptrControlHwnd Then
If pvlngptrParam = WM_MOUSEWHEEL Then
If TypeOf lobjScrollObject Is MSForms.ListBox Or TypeOf lobjScrollObject Is MSForms.ComboBox Then
With lobjScrollObject
If GetKeyState(vbKeyControl) >= 0 Then
If prudtParam.hWnd = SCROLL_DOWN Then
If .TopIndex > 0 Then
If .TopIndex > 3 Then
.TopIndex = .TopIndex - 3
Else
.TopIndex = 0
End If
End If
Else
.TopIndex = .TopIndex + 3
End If
Else
If TypeOf lobjScrollObject Is MSForms.ListBox Then
If prudtParam.hWnd = SCROLL_DOWN Then
Call PostMessageA(llngptrControlHwnd, WM_KEYDOWN, vbKeyLeft, 0)
Else
Call PostMessageA(llngptrControlHwnd, WM_KEYDOWN, vbKeyRight, 0)
End If
End If
End If
End With
ElseIf TypeOf lobjScrollObject Is MSForms.TextBox Then
If GetKeyState(vbKeyControl) >= 0 Then
If prudtParam.hWnd = SCROLL_DOWN Then
Call PostMessageA(llngptrControlHwnd, WM_KEYDOWN, vbKeyUp, 0)
Else
Call PostMessageA(llngptrControlHwnd, WM_KEYDOWN, vbKeyDown, 0)
End If
Else
If prudtParam.hWnd = SCROLL_DOWN Then
Call PostMessageA(llngptrControlHwnd, WM_KEYDOWN, vbKeyLeft, 0)
Else
Call PostMessageA(llngptrControlHwnd, WM_KEYDOWN, vbKeyRight, 0)
End If
End If
ElseIf TypeOf lobjScrollObject Is MSForms.MultiPage Then
With lobjScrollObject.Pages(llngPage)
If GetKeyState(vbKeyControl) >= 0 Then
If prudtParam.hWnd = SCROLL_DOWN Then
If .ScrollTop > 0 Then
.ScrollTop = .ScrollTop - 30
Else
.ScrollTop = 0
End If
Else
.ScrollTop = .ScrollTop + 30
End If
Else
If prudtParam.hWnd = SCROLL_DOWN Then
If .ScrollLeft > 0 Then
.ScrollLeft = .ScrollLeft - 30
Else
.ScrollLeft = 0
End If
Else
.ScrollLeft = .ScrollLeft + 30
End If
End If
End With
ElseIf TypeOf lobjScrollObject Is MSForms.UserForm Or TypeOf lobjScrollObject Is MSForms.Frame Then
With lobjScrollObject
If GetKeyState(vbKeyControl) >= 0 Then
If prudtParam.hWnd = SCROLL_DOWN Then
If .ScrollTop > 0 Then
.ScrollTop = .ScrollTop - 30
Else
.ScrollTop = 0
End If
Else
.ScrollTop = .ScrollTop + 30
End If
Else
If prudtParam.hWnd = SCROLL_DOWN Then
If .ScrollLeft > 0 Then
.ScrollLeft = .ScrollLeft - 30
Else
.ScrollLeft = 0
End If
Else
.ScrollLeft = .ScrollLeft + 30
End If
End If
End With
End If
End If
Else
Call UnhookMouse64
End If
End If
MouseProc = CallNextHookEx(llngptrMouseHook, pvlngCode, pvlngptrParam, ByVal prudtParam)
Exit Function
err_exit:
Call UnhookMouse64
End Function
#End If

Anzeige
AW: Userform in Taskleiste
27.09.2022 11:09:04
volti
Hallo Thomas,
die API ist ein weites Feld und m.E. gerade unter VBA nicht immer einfach. Stellenweise ist VBA z.B. einfach zu langsam oder andere Dinge beißen sich.
Kleinste Code-Abweichungen haben manchmal unerwartete Auswirkungen, wie man ja gerade am aktuellen Code sehen kann.
Warum das mit Nepumuk's Code jetzt nicht mehr richtig funktioniert, das ist mir zu müßig jetzt heraus zu finden.
Dass das grundsätzlich funktionieren kann, kannst Du anhand der Anlage sehen.
Bei mir läuft das Tool (64-Bit) auch mit Mausradscrolling.
Es müsste aber in allen Kombinationen über eine gewisse Zeit getestet werden, es ist nicht ausgeschlossen, dass Situationen eintreten könnten, nach denen es nicht mehr geht.
Userform_Icon_In_Taskleiste.xlsb
Gruß
Karl-Heinz
Anzeige
AW: Userform in Taskleiste
28.09.2022 06:04:42
Thomas
Hi, mit dem Code aus deiner Beispielmappe klappt jetzt auch das Mausrad wieder, keine Ahnung was da sich jetzt gestört hat....
Auch das minimieren und das Icon funktionieren mit dem Code aus deiner Beispielmappe, das einzige was bleibt ist das wenn man eine weitere Excelmappe öffnet dann auch die zuvor ausgeblendete Excelmappe die zum USerform gehört wieder eingeblendet wird....., das ist auch bei deiner Beispielmappe so.
Vielen Dank für deine Hilfe und erklärungen.
AW: Userform in Taskleiste
28.09.2022 06:48:29
Oberschlumpf
und man kann doch nicht ein Hochhaus nur mit Wasser + Mehl bauen
AW: Userform in Taskleiste
01.10.2022 19:43:27
Thomas
Was möchtest du mir damit sagen?
AW: Userform in Taskleiste
27.09.2022 05:00:39
Thomas
Hi, vielen Dank für die Ausführliche Antwort, mein erstes Windows war zwar 3.0 und ich hab da ein bisschen mit QBasic rumexperimentiert mehr aber auch nicht, aber wenn ich dich richtig verstehe, dann wäre ein Buch in richtung Windows Programmierung der richtige ansatz oder auch die google suche nach sowas wie Windows Programmierung.
Die Links werde ich mir mal ansehen.
Danke
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige