Live-Forum - Die aktuellen Beiträge
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 und weitere Exceldateien

Userform und weitere Exceldateien
04.10.2022 11:38:54
Thomas
Hallo,
bezugnehmende auf diesen Thread
https://www.herber.de/forum/cgi-bin/callthread.pl?index=1900000#1900000
habe ich noch ein paar kleine Probleme/ "unschönheiten" mit der Lösung, das eine ist wie auch in dem Thread schon erwähnt, das wenn das Userform aktiv ist und die Excel Anwendung ausgeblendet ist, das wenn man dann eine weitere Exceldatei öffnet auch wieder die Excelarbeitsmappe wo das Userform drin ist in den Vordergrund kommt und wieder Sichtbar ist, was so nicht sein sollte.
Weiterhin passiert auch der Fall, das wenn schon eine Exceldatei geöffnet ist und dann die Datei mit dem Userform geöffnet wird, das dann die vorher geöffnete Datei ausgeblendet wird.
Kann man das noch irgendwie abfangen/anpassen? Der aktuelle Code der dank @Volti eingeflossen ist, ist dieser.

' 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
'Benötigt um das Userform minimieren zu können.
Const GWL_HWNDPARENT = (-8)
Const GWL_STYLE = -16&
Const WS_CAPTION = &HC00000                               ' >>>>
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
' >>>>
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 '              ' >>>>
' DrawMenuBar mhWndUF                                       ' >>>>
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 >>>>
Application.Visible = False                               ' Excel anzeigen aus
Private Sub UserForm_Activate()
Const GWL_EXSTYLE = -20
Const WS_EX_APPWINDOW = &H40000
Dim i As Integer
ShowWindow mhWndUF, 1        ' 1 = SW_HIDE                ' UF anzeigen ein
SetWindowLongA mhWndUF, GWL_EXSTYLE, GetWindowLongA(mhWndUF, GWL_EXSTYLE) _
Or WS_EX_APPWINDOW                ' Fensterstyle ändern
SetTaskBar "Dialogbox " & Caption & " wieder aktivieren"  ' >>>>
End Sub
'Benötigte Prozeduren um das Userform zu minimieren, sowie das Icon des USerfirms in der Taskleiste darzustellen
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
Application.Visible = False
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
Danke

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
keine Hilfe, aber...
04.10.2022 14:50:03
Oberschlumpf
Hi Thomas,
meinst du nicht, dass du echt langsam ganz schön übertreibst?
Ein Frage/Antwort-Forum (egal, welcher Fachbereich) ist dazu da, vielen Fragenden Hilfestellung zu leisten, wenn sie alleine - mit einer! oder zwei! ok, von mir aus auch drei! Fragen....erst mal!....nicht weiterkommen.
Aber es wird...nein, falsch...ich würd mich freuen, wenn die Fragenden nach sehr vielen! Hilfe-Ideen es auch mal gut sein lassen mit einer Meldung wie z Bsp "Ok, danke für eure Hilfe, wir haben viel versucht...hat leider nicht funktioniert"
Nein, mecker jetzt nicht rum, dass ich nicht will, dass man auch dir hilft.
Natürlich soll auch dir geholfen werden!
Und Karheinz hat echt sooooooo viel Geduld bei dir gezeigt!
Aber jetzt, wo du - schon wieder - einen neuen Beitrag mit dem selben Problem (oder eher ein Problem, welches sich aus anderen Problemen mit sehr ähnlicher Fragestellung ergeben hat) erstellt hast, finde ich: DU nutzt das echt sehr aus! Und mich nervt das.
Ich würde gern mal wissen, wieviel Geld du schon gespart hast, weil du ja nicht einen Auftrags-Programmierer fragen musst....dir wird ja hier geholfen...zumindest wird es versucht - erwähnte ich schon meinen Verdacht einer Ausnutzung?
Ja, ich weiß, ich bin der Böse, weil ich klar + deutlich schreibe, was ich denke.
Aber is nich schlimm, jeder darf ja seine Meinung äußern, ohne andere damit zu verletzen,beleidigen, usw...ich auch.
Dieser Beitrag ist von mir allein. Ich will niemanden einschränken. Jeder kann tun, was er möchte - du kannst natürlich weiter das Gleiche (oder sehr, sehr Ähnliche) fragen - Karlheinz und jeder kann weiter helfen, wenn er noch Ideen hat...
Ciao
Thorsten
Anzeige
AW: keine Hilfe, aber...
04.10.2022 17:26:03
onur
Sowas kotzt mich auch jedes Mal an. Es gibt Leute, die haben kein Interesse dran, fischen zu lernen, die wollen nur Fische abstauben, am -besten schon ausgenommen und vorgebraten auf dem Teller serviert.
Aber soviel man auch meckert, es bringt nix, denn irgend Jemand aus dem Forum wird sowieso wieder einmal helfen.
AW: keine Hilfe, aber...
05.10.2022 05:24:05
Thomas
Hallo Onur,
mal davon abgesehen das ich Fisch nicht sonderlich mag, hab ich grade auf Thorstens Beitrag geantwortet, das das so nicht meine Absicht war/ist und auch nicht ganz korrekt ist. Ich habe mittlerweile (in ca. den letzten 10 Monaten) 3 Bücher zu Excel und VB gelesen(da ich es gerne lernen möchte ohne Fragen zu müssen), aber wirklich lernen tut man es dann glaub ich erst durch tun und ausprobieren und daraus entstehen dann aber wieder Probleme und Fragen, daher die ggf. zu vielen Fragen hier. Werde versuchen mich zu bessern.....
Anzeige
AW: keine Hilfe, aber...
05.10.2022 05:20:13
Thomas
Hallo Thorsten,
Danke für deine Meinung und nein für mich bist du deshalb nicht der Böse, denn wie du schon sagst, jeder hat das recht seine Meinung offen zu äußern. Was daran definitiv allerdings nicht korrekt ist ist das es ums ausnutzen/Geld sparen geht. Du hast absolut recht das Karl-Heinz mit viel Geduld und auch Arbeit eine tolle Lösung gefunden hat, was ich mit meinen aktuellen Kenntnissen im leben nicht hinbekommen hätte, aber solche beispiele helfen ja auch zu lernen, und daraus war bis jetzt für mich schon das ich mir zu dem Thema Windows Api ein Buch gekauft habe um mich mehr mit dem Thema zu beschäftigen (was mit sicherheit einige Zeit brauchen wird, da das Buch recht Dick ist und ich das als Hobby mache..)
Die erneute Frage zu dem Thema kam ja nur in sofern auf das der "alte" Thread ins Archiv gewandert ist und ich nun beim Testen/weiter machen halt nochmal über eine neue Besonderheiten gestolpert bin (das schon geöffnete Excelmappen nun "verschwinden") und es das bestehende "Problem" das beim öffnen einer neuen Mappe die Excelmappe eingeblendet wird auch noch da war, in der Hoffnung das dazu noch einer eine Idee hat.
Wenn es wie ausnutzen rüber gekommen ist, dann möchte ich mich dafür entschuldigen das ist nicht meine Absicht, hab halt grade Spaß an der Thematik gefunden und versuche alles mögliche für mich zu basteln und da stolpere ich immer wieder über neue Probleme bei der Umsetzung meiner Ideen.
MFG
Thomas
Anzeige
AW: Userform und weitere Exceldateien
07.10.2022 05:59:58
Thomas
@Karl-Heinz, ich habe jetzt mal noch etwas getestet und mir ist bei dem Mausrad noch ein seltsames verhalten aufgefallen, z.b. in einer Kombobox scrollt es immer nach unten, egal in welche richtung ich das Mausrad drehe es wird immer von A-Z gescrollt, nie anders rum. Woran kann das liegen?
Deinen Code hatte ich so übernommen, im Modul

Option Explicit
' 02.02.2022 Karl-Heinz Voltmann, Freigericht
' Mousewheeling in Userform-Controls für 64 und 32 Bit-Office (ohne LongLong)
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
ByVal xPoint As Long, ByVal yPoint As Long) 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
#Else
Private Declare PtrSafe Function GetWindowLongA Lib "user32" ( _
ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
#End If
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 Type MOUSEHOOKSTRUCT
PT           As POINTAPI
lScroll      As LongPtr
wHitTestCode As Long
dwExtraInfo  As LongPtr
End Type
Private mhHook    As LongPtr
Private mhWndCtrl As LongPtr
Private Const ciStep        As Integer = 1  ' >>>
Private Const WH_MOUSE_LL   As Long = 14
Private Const GWL_HINSTANCE As Long = -6
Private Const WM_KEYDOWN    As Long = &H100
Private mlPage              As Long
Private moControl           As MSForms.Control
Public Sub HookMouse(ByRef oControl As MSForms.Control, Optional ByVal lPage As Long)
' Hook-Prozedur zum Abfangen der Mausaktivitäten setzen
' Wird nur bei Mausbewegungen im Control angesprungen
mlPage = lPage
If mhWndCtrl  GetHandleUnderMouse Then                          ' Wenn neues Control oder keins mehr
Call UnhookMouse                                               ' Maus unhooken
Set moControl = oControl                                       ' Control global machen
mhWndCtrl = GetHandleUnderMouse                                ' Gleichheit merken
If mhHook = 0 Then                                             ' Maushook setzen, wenn nicht schon aktiv
mhHook = SetWindowsHookExA(WH_MOUSE_LL, AddressOf MouseProc, _
GetWindowLongA(mhWndCtrl, GWL_HINSTANCE), 0&)
End If
End If
End Sub
Public Sub UnhookMouse()
If mhHook  0 Then                                               ' Wenn Maus bereits gehookt
UnhookWindowsHookEx mhHook                                     ' Maus unhooken
Set moControl = Nothing                                        ' Objekt zurücksetzen
mhHook = 0: mhWndCtrl = 0                                      ' Parameter leeren
End If
End Sub
Private Function GetHandleUnderMouse() As LongPtr
Dim PT As POINTAPI
GetCursorPos PT
GetHandleUnderMouse = WindowFromPoint(PT.X, PT.Y)
End Function
Private Function MouseProc(ByVal nCode As Long, ByVal wParam As LongPtr, ByRef lParam As MOUSEHOOKSTRUCT) As LongPtr
Dim oControl As MSForms.Control, bScrollDown As Boolean, lKeyLeftRight As Long
Set oControl = moControl
On Error GoTo Fehler
If nCode = 0 Then ' 0 = HC_ACTION
If mhWndCtrl = GetHandleUnderMouse() Then                       ' Ist Maus über dem Control?
If wParam = &H20A Then  ' WM_MOUSEWHEEL-Message              ' Mausradaktion verarbeiten
bScrollDown = lParam.lScroll = &H780000                   ' Hoch/runter bzw. links/rechts scrollen?
lKeyLeftRight = IIf(bScrollDown, vbKeyLeft, vbKeyRight)   ' Taste für links oder rechts setzen
If TypeOf oControl Is MSForms.MultiPage Then Set oControl = oControl.Pages(mlPage)
With oControl
If TypeOf oControl Is MSForms.TextBox Then
If GetKeyState(vbKeyControl) >= 0 Then              ' Hoch/Runter scrollen
.CurLine = IIf(bScrollDown, IIf(.CurLine > ciStep, .CurLine - ciStep, 0), .CurLine + ciStep)
Else                                                ' Links/rechts scrollen
PostMessageA mhWndCtrl, WM_KEYDOWN, ByVal lKeyLeftRight, 0
End If
ElseIf TypeOf oControl Is MSForms.ListBox Then
If GetKeyState(vbKeyControl) >= 0 Then              ' Hoch/runter scrollen
.TopIndex = IIf(bScrollDown, IIf(.TopIndex > ciStep, .TopIndex - ciStep, 0), .TopIndex + ciStep)
Else                                                ' Links/rechts scrollen
PostMessageA mhWndCtrl, WM_KEYDOWN, ByVal lKeyLeftRight, 0
End If
ElseIf TypeOf oControl Is MSForms.ComboBox Then        ' Hoch/runter scrollen
.TopIndex = IIf(bScrollDown, IIf(.TopIndex > ciStep, .TopIndex - ciStep, 0), .TopIndex + ciStep)
Else 'MSForms.MultiPage,MSForms.Userform, MSForms.Frame
If GetKeyState(vbKeyControl) >= 0 Then              ' Hoch/runter scrollen
.ScrollTop = IIf(bScrollDown, IIf(.ScrollTop > 30, .ScrollTop - 30, 0), .ScrollTop + 30)
Else                                               ' Links/rechts scrollen
.ScrollLeft = IIf(bScrollDown, IIf(.ScrollLeft > 30, .ScrollLeft - 30, 0), .ScrollLeft + 30)
End If
End If
End With
Exit Function
End If
Else
Call UnhookMouse
End If
End If
MouseProc = CallNextHookEx(mhHook, nCode, wParam, ByVal lParam)    ' Message an nächsten Prozess weiterleiten
Exit Function
Fehler:
Call UnhookMouse
End Function
und dann der aufruf über

Private Sub cobAuswahl_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call HookMouse(cobAuswahl)
End Sub
Danke
Anzeige
AW: Userform und weitere Exceldateien
08.10.2022 11:53:03
Planlos
Hallo
weiß nicht wie du den Code bei dir eingbaut hast und der Code verhält sich zwar bei 64bit in einem bestimmten Bereich ein wenig anders als bei 32bit weil eine Funktion falsch deklariert wurde, aber scrollen tut er trotzdem in beiden Bitversionen hoch und runter mit dem Mouserad.
AW: Userform und weitere Exceldateien
10.10.2022 05:18:46
Thomas
Hi @Planlos, bei mir leider nicht, hab den Code wie oben angegeben eingebaut. Im Modul modMausrad liegt der Code

Option Explicit
' 02.02.2022 Karl-Heinz Voltmann, Freigericht
' Mousewheeling in Userform-Controls für 64 und 32 Bit-Office (ohne LongLong)
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare PtrSafe Function WindowFromPoint Lib "user32" ( _
ByVal xPoint As Long, ByVal yPoint As Long) 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
#Else
Private Declare PtrSafe Function GetWindowLongA Lib "user32" ( _
ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
#End If
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 Type MOUSEHOOKSTRUCT
PT           As POINTAPI
lScroll      As LongPtr
wHitTestCode As Long
dwExtraInfo  As LongPtr
End Type
Private mhHook    As LongPtr
Private mhWndCtrl As LongPtr
Private Const ciStep        As Integer = 1  ' >>>
Private Const WH_MOUSE_LL   As Long = 14
Private Const GWL_HINSTANCE As Long = -6
Private Const WM_KEYDOWN    As Long = &H100
Private mlPage              As Long
Private moControl           As MSForms.Control
Public Sub HookMouse(ByRef oControl As MSForms.Control, Optional ByVal lPage As Long)
' Hook-Prozedur zum Abfangen der Mausaktivitäten setzen
' Wird nur bei Mausbewegungen im Control angesprungen
mlPage = lPage
If mhWndCtrl  GetHandleUnderMouse Then                          ' Wenn neues Control oder keins mehr
Call UnhookMouse                                               ' Maus unhooken
Set moControl = oControl                                       ' Control global machen
mhWndCtrl = GetHandleUnderMouse                                ' Gleichheit merken
If mhHook = 0 Then                                             ' Maushook setzen, wenn nicht schon aktiv
mhHook = SetWindowsHookExA(WH_MOUSE_LL, AddressOf MouseProc, _
GetWindowLongA(mhWndCtrl, GWL_HINSTANCE), 0&)
End If
End If
End Sub
Public Sub UnhookMouse()
If mhHook  0 Then                                               ' Wenn Maus bereits gehookt
UnhookWindowsHookEx mhHook                                     ' Maus unhooken
Set moControl = Nothing                                        ' Objekt zurücksetzen
mhHook = 0: mhWndCtrl = 0                                      ' Parameter leeren
End If
End Sub
Private Function GetHandleUnderMouse() As LongPtr
Dim PT As POINTAPI
GetCursorPos PT
GetHandleUnderMouse = WindowFromPoint(PT.X, PT.Y)
End Function
Private Function MouseProc(ByVal nCode As Long, ByVal wParam As LongPtr, ByRef lParam As MOUSEHOOKSTRUCT) As LongPtr
Dim oControl As MSForms.Control, bScrollDown As Boolean, lKeyLeftRight As Long
Set oControl = moControl
On Error GoTo Fehler
If nCode = 0 Then ' 0 = HC_ACTION
If mhWndCtrl = GetHandleUnderMouse() Then                       ' Ist Maus über dem Control?
If wParam = &H20A Then  ' WM_MOUSEWHEEL-Message              ' Mausradaktion verarbeiten
bScrollDown = lParam.lScroll = &H780000                   ' Hoch/runter bzw. links/rechts scrollen?
lKeyLeftRight = IIf(bScrollDown, vbKeyLeft, vbKeyRight)   ' Taste für links oder rechts setzen
If TypeOf oControl Is MSForms.MultiPage Then Set oControl = oControl.Pages(mlPage)
With oControl
If TypeOf oControl Is MSForms.TextBox Then
If GetKeyState(vbKeyControl) >= 0 Then              ' Hoch/Runter scrollen
.CurLine = IIf(bScrollDown, IIf(.CurLine > ciStep, .CurLine - ciStep, 0), .CurLine + ciStep)
Else                                                ' Links/rechts scrollen
PostMessageA mhWndCtrl, WM_KEYDOWN, ByVal lKeyLeftRight, 0
End If
ElseIf TypeOf oControl Is MSForms.ListBox Then
If GetKeyState(vbKeyControl) >= 0 Then              ' Hoch/runter scrollen
.TopIndex = IIf(bScrollDown, IIf(.TopIndex > ciStep, .TopIndex - ciStep, 0), .TopIndex + ciStep)
Else                                                ' Links/rechts scrollen
PostMessageA mhWndCtrl, WM_KEYDOWN, ByVal lKeyLeftRight, 0
End If
ElseIf TypeOf oControl Is MSForms.ComboBox Then        ' Hoch/runter scrollen
.TopIndex = IIf(bScrollDown, IIf(.TopIndex > ciStep, .TopIndex - ciStep, 0), .TopIndex + ciStep)
Else 'MSForms.MultiPage,MSForms.Userform, MSForms.Frame
If GetKeyState(vbKeyControl) >= 0 Then              ' Hoch/runter scrollen
.ScrollTop = IIf(bScrollDown, IIf(.ScrollTop > 30, .ScrollTop - 30, 0), .ScrollTop + 30)
Else                                               ' Links/rechts scrollen
.ScrollLeft = IIf(bScrollDown, IIf(.ScrollLeft > 30, .ScrollLeft - 30, 0), .ScrollLeft + 30)
End If
End If
End With
Exit Function
End If
Else
Call UnhookMouse
End If
End If
MouseProc = CallNextHookEx(mhHook, nCode, wParam, ByVal lParam)    ' Message an nächsten Prozess weiterleiten
Exit Function
Fehler:
Call UnhookMouse
End Function
und im Userform sind dann die Aufrufe drin für die einzelnen Controls

Private Sub cobAuswahl_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Call HookMouse(cobAuswahl)
End Sub
Ich glaube das sich das irhendwo bei mir mit dem Minimieren des Userforms beisst....
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige