2

VBAを使用してExcel 2010で作成したユーザーフォームがあります。コントロールは、特定のシートのデータに基づいてプログラムによってフォームに追加されます。私のコードはすべてのコントロールを追加し、フォームが長すぎるかどうかを判断します。そうである場合、フォームは最大 500px の高さに設定され、スクロールが有効になります。

スクロールバーをクリックすると、スクロールバーが表示され、期待どおりに機能しますが、マウスのスクロールホイールはフォームのスクロールバーに影響しません。

マウス ホイールのスクロールを有効にするためのプロパティは見たことがありません。Google で見つけたすべての記事は、UserForm 自体ではなく、UserForm (ListBox、ComboBox など) 内のスクロール コントロールを指しています。私が見つけた他の記事は、初期設定ではマウス ホイールのスクロールをサポートしていなかった Excel 2003 にさかのぼるものです。

ここで何が起こっているのか誰にも分かりませんか?

スクロールを有効にするコードは次のとおりです。

If Me.height > 500 Then
    Me.ScrollHeight = Me.height
    Me.ScrollBars = fmScrollBarsVertical
    Me.KeepScrollBarsVisible = fmScrollBarsVertical
    Me.height = 500
    Me.Width = Me.Width + 12
End If

Windows 7 64 ビット ラップトップで Excel 2010 (32 ビット) を使用しています。同じセットアップを実行している他のコンピューターでも同じ問題が発生しています。これをテストするための別の構成にアクセスできません。

4

1 に答える 1

2

32 ビット Excel でのみ動作するようにできます。このコードは、64 ビット Excel ではまったくコンパイルおよび実行されません。32ビットと64ビットの両方と互換性のある(もう少し複雑な)バージョンを作成しましたが、64ビットではスクロールしませんが、少なくともコンパイルされます(誰かがその64ビットを必要とする場合はお知らせください-ビット互換コード)。

したがって、新しいモジュールを作成し、そこに WinAPI 呼び出し用のコードを貼り付けます。

Option Explicit 
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
   (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
      (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
      (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Const GWL_STYLE As Long = (-16)           'The offset of a window's style
Private Const WS_SYSMENU As Long = &H80000        'Style to add a system menu
Private Const WS_MINIMIZEBOX As Long = &H20000    'Style to add a Minimize box on the title bar
Private Const WS_MAXIMIZEBOX As Long = &H10000    'Style to add a Maximize box to the title bar
'To be able to scroll with mouse wheel within Userform
Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" ( _
    ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, _
    ByVal lParam As Long) As Long

Private Const GWL_WNDPROC = -4
Private Const WM_MOUSEWHEEL = &H20A
Dim LocalHwnd As Long
Dim LocalPrevWndProc As Long
Dim myForm As UserForm
Private Function WindowProc(ByVal Lwnd As Long, ByVal Lmsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'To handle mouse events
Dim MouseKeys As Long
Dim Rotation As Long
If Lmsg = WM_MOUSEWHEEL Then
    MouseKeys = wParam And 65535
    Rotation = wParam / 65536
    'My Form s MouseWheel function
'=================================================================
    YOUR_USERFORM_NAME_HERE.MouseWheel Rotation
'=================================================================
End If
WindowProc = CallWindowProc(LocalPrevWndProc, Lwnd, Lmsg, wParam, lParam)
End Function
Public Sub WheelHook(PassedForm As UserForm)
'To get mouse events in userform
On Error Resume Next
Set myForm = PassedForm
LocalHwnd = FindWindow("ThunderDFrame", myForm.Caption)
LocalPrevWndProc = SetWindowLong(LocalHwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub WheelUnHook()
'To Release Mouse events handling
Dim WorkFlag As Long
On Error Resume Next
WorkFlag = SetWindowLong(LocalHwnd, GWL_WNDPROC, LocalPrevWndProc)
Set myForm = Nothing
End Sub

次に、ユーザーフォームに簡単なコードを追加します...(「frames_(mouseOverFrame_)」をスクロールするUIコントロールの名前に置き換えることを忘れないでください)。

Public Sub MouseWheel(ByVal Rotation As Long)
'************************************************
' To respond from MouseWheel event
' Scroll accordingly to direction
'
' Made by:  Mathieu Plante
' Date:     July 2004
'************************************************
Select Case frames_(mouseOverFrame_).ScrollTop - Sgn(Rotation) * 18
Case Is < 0
frames_(mouseOverFrame_).ScrollTop = 0
Case Is > frames_(mouseOverFrame_).ScrollHeight
frames_(mouseOverFrame_).ScrollTop = frames_(mouseOverFrame_).ScrollHeight
Case Else
frames_(mouseOverFrame_).ScrollTop = frames_(mouseOverFrame_).ScrollTop - Sgn(Rotation) * 18
End Select
End Sub

3 つの異なるフレーム (現在マウス カーソルの下にあるフレームに応じて) をスクロールしたかったので、3 つのフレームのコレクションを作成し、各フレームで「MouseMove」イベントを使用して、フレーム番号を「mouseOverFrame_」変数に割り当てました。したがって、マウスが最初のフレームなどに移動すると、スクローラーは「mouseOverFrame_」変数内に「1」を入れることで、どのフレームをスクロールするかを認識します...

于 2013-11-22T12:33:13.607 に答える