[AccessD] record scroll

Darryl Collins Darryl.Collins at coles.com.au
Thu May 22 00:15:34 CDT 2008


Replied off list with attached file: Here is the body of the solution.  The attached file can be created by yourself using the MS link in this email.  You need VB6 to do this.  I am going to upload this file and email content to my website tonight at: www.excelyourbusiness.com.au so others can use it.  It took me days and days to sort all this out and if I can save other the trouble than I am most happy.

John, if you have further questions feel free to contact me offlist.

cheers
Darryl

<copied email follows>

'-----

Hey John - To make the mouse wheel behave in Access as the user expects I had to do the following.  It took days of research to make this work as I could not access the registry or have any admin rights and IT techs wouldn't install the file automatically.  Don't freak out as more than half of this email is code used to ensure the DAO350.dll and Mousewheel.dll files are registered correctly. If you have admin rights then you can skip all that bit without bother.  NOTE!! You will have to change/check the directory paths in some of that code.

Anyway.. here is what you do.

PART ONE

1: MOUSE WHEEL SUPPORT
' ---------------------------------------------------------------------------------------------------------

Download and install Freewheel. It is free, non hostile, don't need to register and don't need admin rights to install. I have used on personal PC's and on multiple corporate networks for years without any hassles ever.  It will ensure the mouse wheel behaves as the user expects, although it does not prevent the skipping between records issue.

http://www.geocities.com/SiliconValley/2060/freewheel.html
Personally, this is the one I would recommend as it fixes the mouse wheel problem *everywhere* in all apps - it just works.

Microsoft also have a solution (at least for the VBE - not sure if it fixes all mouse wheel issues in other apps or not).
http://office.microsoft.com/en-us/help/HA101175901033.aspx
That you may wish to consider if you don't want to use freewheel, however you need admin rights and registry access to do this.


2: MouseWheel.dll
' ------------------------------------------------------------------------------------------------
"MouseWheel.dll" is used to capture the mouse wheel event and prevent the user from using the mouse wheel to jump between records.   

MouseWheel.dll source code and details are located here: http://support.microsoft.com/kb/278379.  I have already made this file and attached it for you to this email. I am providing the link in case there is some issue about using a dll file that you didn't make and it also give your instructions in case I foul this email up somewhere.

If you get this error http://support.microsoft.com/kb/292054 . The DAO350.dll and Mousewheel.dll file need to be registered.  You can normally do this via the START > RUN option (see the MS link for details) or you can workaround this by opening the VBE in MS Access, un-reference and then re-reference the MouseWheel.dll file manually and restart. However this is clearly not acceptable if you are not the end user. If you are like me and your corporate PC is locked down tighter than a snake bum and/or the above options are unavailable to you then I have code which will automatically register the dll files for you which I have posted at the bottom of this email.

In addition to the dll file you will need to do the following.

Create a regular code module in the VBE - Call it "basSubClassWindow" and copy and paste the following code into it.

' =========== START CODE =====================

Option Compare Database
Option Explicit

Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
    (ByVal hwnd As Long, _
    ByVal nIndex As Long, _
    ByVal dwNewLong As Long) As Long

Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
    (ByVal lpPrevWndFunc As Long, _
     ByVal hwnd As Long, _
     ByVal msg As Long, _
     ByVal wParam As Long, _
     ByVal lParam As Long) As Long
     
     
Public Const GWL_WNDPROC = -4
Public Const WM_MouseWheel = &H20A
Public lpPrevWndProc As Long
Public CMouse As CMouseWheel

Public Function WindowProc(ByVal hwnd As Long, _
    ByVal uMsg As Long, _
    ByVal wParam As Long, _
    ByVal lParam As Long) As Long

    'Look at the message passed to the window. If it is
    'a mouse wheel message, call the FireMouseWheel procedure
    'in the CMouseWheel class, which in turn raises the MouseWheel
    'event. If the Cancel argument in the form event procedure is
    'set to False, then we process the message normally, otherwise
    'we ignore it.  If the message is something other than the mouse
    'wheel, then process it normally
    Select Case uMsg
        Case WM_MouseWheel
            CMouse.FireMouseWheel
            If CMouse.MouseWheelCancel = False Then
                WindowProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam, lParam)
            End If
           
            
        Case Else
           WindowProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam, lParam)
    End Select
End Function

' =========== END CODE =====================


Now for each form you want to restrict the mouse wheel you need to add the following code in the FORM code module

' =========== START CODE =====================

Option Compare Database
Option Explicit

Private WithEvents clsMouseWheel As MouseWheel.CMouseWheel

Private Sub Form_Load()
    On Error GoTo Form_Load_Error
   
    Set clsMouseWheel = New MouseWheel.CMouseWheel
    Set clsMouseWheel.Form = Me
    clsMouseWheel.SubClassHookForm

   'On Error GoTo 0
   Exit Sub

Form_Load_Error:

    'MsgBox "Mouse Wheel Restrictor File Needs Attention, Please Contact PMO Group for Assistance", vbInformation, "Contact PMO Group..."
End Sub

Private Sub Form_Close()
   On Error GoTo Form_Close_Error

   clsMouseWheel.SubClassUnHookForm
   Set clsMouseWheel.Form = Nothing
   Set clsMouseWheel = Nothing

   'On Error GoTo 0
   Exit Sub

Form_Close_Error:

    'MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Form_Close of VBA Document Form_frm_SubCurrentAchievments"
End Sub

Private Sub clsMouseWheel_MouseWheel(Cancel As Integer)
    MsgBox "You cannot use the mouse wheel to scroll records."
    Cancel = True
End Sub

' =========== END CODE =====================


PART TWO (only needed if you get the dreaded 429 Active X error)

That should work fine for you - However as I couldn't register the mousewheel.dll file the 'normal' way I kept getting "Active X 429 - Cannot create object" Error.  If you are getting this then apply the following fix.

IN CASE OF ACTIVE X 429 ERROR.
Create a normal code module and call it "Function_DaoReg" - then copy the following code

' =========== START CODE =====================

Option Compare Database
Option Explicit

'http://www.trigeminal.com/usenet/usenet026.asp
'http://www.trigeminal.com/code/RegisterDao.bas

Private Const HKEY_LOCAL_MACHINE = &H80000002
Public Const KEY_QUERY_VALUE = &H1
Public Const ERROR_SUCCESS = 0&
Public Const MAX_PATH = 260
Public Const S_OK = &H0

Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long

Private Declare Function RegDaoDll Lib "dao360.dll" Alias "DllRegisterServer" () As Long

Private Const REGKEY As String = "SOFTWARE\Microsoft\Windows\CurrentVersion"
Private Const REGVAL As String = "CommonFilesDir"
Private Const DLLLOCATION As String = "\Microsoft Shared\DAO\dao360.dll"

Public Function DaoReg() As Boolean
Dim hKey As Long
Dim stName As String
Dim cb As Long
Dim hMod As Long
    ' First, find DAO. Ordinarily we could call the shell32/shfolder
    ' functions to find the location of the "Common Files" folder,
    ' but this will not work on Windows 95. So, go right to the
    ' registry to find:
    '   $(PROGRAM FILES)\$(COMMON FILES)\Microsoft Shared\DAO
    
    If (ERROR_SUCCESS = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_QUERY_VALUE, hKey)) Then
        cb = MAX_PATH
        stName = String$(cb, vbNullChar)
                
        If (ERROR_SUCCESS = RegQueryValueEx(hKey, REGVAL, 0&, ByVal 0&, ByVal stName, cb)) Then
            ' Ok, now build the full DLL path
            stName = StFromSz(stName) & DLLLOCATION
            
            ' Load DAO so we can try to register it
            hMod = LoadLibrary(stName)
            If hMod Then
                ' Find out if the registration works
                DaoReg = (RegDaoDll() = S_OK)
                
                Call FreeLibrary(hMod)
            End If
        End If
        Call RegCloseKey(hKey)
    End If
End Function

'------------------------------------------------------------
'   StFromSz
'
'    Find the first vbNullChar in a string, and return
'    everything prior to that character. Extremely
'    useful when combined with the Windows API function calls.
'------------------------------------------------------------
Public Function StFromSz(ByVal sz As String) As String
    
    Dim ich As Integer
    
    ich = InStr(sz, vbNullChar)
    Select Case ich
        ' It's best to put the most likely case first.
        Case Is > 1
            ' Found in the string, so return the portion
            ' up to the null character.
            StFromSz = Left$(sz, ich - 1)
        Case 0
            ' Not found at all, so just
            ' return the original value.
            StFromSz = sz
        Case 1
            ' Found at the first position, so return an empty string.
            StFromSz = vbNullString
    End Select
End Function

' =========== END CODE =====================

Create another code module, call it "Function_RegisterMouseWheel" and add in the following code

' =========== START CODE =====================

Option Compare Database
Option Explicit

'http://www.trigeminal.com/usenet/usenet026.asp
'http://www.trigeminal.com/code/RegisterDao.bas

Private Const HKEY_LOCAL_MACHINE = &H80000002
Public Const KEY_QUERY_VALUE = &H1
Public Const ERROR_SUCCESS = 0&
Public Const MAX_PATH = 260
Public Const S_OK = &H0

Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long

Private Declare Function RegDaoDll Lib "MouseWheel.dll" Alias "DllRegisterServer" () As Long

'\\dingo\grpdata\IT Project Status Reporting\Icons\MouseWheel.dll

Private Const REGKEY As String = "SOFTWARE\Microsoft\Windows\CurrentVersion"
Private Const REGVAL As String = "CommonFilesDir"
Private Const DLLLOCATION As String = "\\dingo\grpdata\IT Project Status Reporting\Icons\MouseWheel.dll"

Public Function DaoMouseWheel() As Boolean
Dim hKey As Long
Dim stName As String
Dim cb As Long
Dim hMod As Long
    ' First, find DAO. Ordinarily we could call the shell32/shfolder
    ' functions to find the location of the "Common Files" folder,
    ' but this will not work on Windows 95. So, go right to the
    ' registry to find:
    '   $(PROGRAM FILES)\$(COMMON FILES)\Microsoft Shared\DAO
    
    If (ERROR_SUCCESS = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_QUERY_VALUE, hKey)) Then
        cb = MAX_PATH
        stName = String$(cb, vbNullChar)
                
        If (ERROR_SUCCESS = RegQueryValueEx(hKey, REGVAL, 0&, ByVal 0&, ByVal stName, cb)) Then
            ' Ok, now build the full DLL path
            stName = DLLLOCATION 'StFromSz(stName) &
            
            ' Load DAO so we can try to register it
            hMod = LoadLibrary(stName)
            If hMod Then
                ' Find out if the registration works
                DaoMouseWheel = (RegDaoDll() = S_OK)
                
                Call FreeLibrary(hMod)
            End If
        End If
        Call RegCloseKey(hKey)
    End If
End Function

'------------------------------------------------------------
'   StFromSz
'
'    Find the first vbNullChar in a string, and return
'    everything prior to that character. Extremely
'    useful when combined with the Windows API function calls.
'------------------------------------------------------------
Public Function StFromSz(ByVal sz As String) As String
    
    Dim ich As Integer
    
    ich = InStr(sz, vbNullChar)
    Select Case ich
        ' It's best to put the most likely case first.
        Case Is > 1
            ' Found in the string, so return the portion
            ' up to the null character.
            StFromSz = Left$(sz, ich - 1)
        Case 0
            ' Not found at all, so just
            ' return the original value.
            StFromSz = sz
        Case 1
            ' Found at the first position, so return an empty string.
            StFromSz = vbNullString
    End Select
End Function

' =========== END CODE =====================

Create a 3rd module, call it "CreateMouseWheelRef_" and add the following code

' =========== START CODE =====================
Option Compare Database
Option Explicit

Sub CreateMouseWheelReference()

Dim sPATH As String
Dim ref As Access.Reference

For Each ref In References
    If ref.IsBroken = True Then
        On Error Resume Next
        Access.References.Remove ref
    End If
Next ref

For Each ref In References
    If ref.name = "MouseWheel" Then
        If ref.IsBroken = True Then
            Access.References.Remove ref
        Else
            Exit Sub
        End If
    End If
Next ref

sPATH = "\\dingo\grpdata\IT Project Status Reporting\Icons\MouseWheel.dll"
'sPATH = "\\goanna\grpdata\PMO Team\DarrylCollins\Test Database\Icons\MouseWheel.dll"

If ReferenceFromFile(sPATH) = True Then
    MsgBox "Reference set successfully. Automatic Compile will take approx 30 seconds...", vbInformation, "Please Note:"
Else
    MsgBox "MouseWheel Reference not set successfully. - Please Contact PMO for Advice.", vbCritical, "Action Required!"
    'Application.Quit
End If

' Call a hidden SysCmd to automatically compile/save all modules.
Call SysCmd(504, 16483)

End Sub

' =========== END CODE =====================


Then in the MAIN MENU or Startup FORM when the database opens place the following code

' =========== START CODE =====================
Private Sub Form_Open(Cancel As Integer)

DoCmd.Maximize

Call DaoReg
Call DaoMouseWheel
Call CreateMouseWheelReference

' =========== END CODE =====================




-----Original Message-----
From: John Eget [mailto:joeget at vgernet.net]
Sent: Thursday, 22 May 2008 2:38 PM
To: Darryl Collins
Subject: Re: [AccessD] record scroll


YES IT IS!!!!!!!


This email and any attachments may contain privileged and confidential information and are intended for the named addressee only. If you have received this e-mail in error, please notify the sender and delete this e-mail immediately. Any confidentiality, privilege or copyright is not waived or lost because this e-mail has been sent to you in error. It is your responsibility to check this e-mail and any attachments for viruses.  No warranty is made that this material is free from computer virus or any other defect or error.  Any loss/damage incurred by using this material is not the sender's responsibility.  The sender's entire liability will be limited to resupplying the material.




More information about the AccessD mailing list