1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
Option Compare Database
Option Explicit
' Constantes
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5
Private Const SIF_RANGE = &H1
Private Const SIF_PAGE = &H2
Private Const SIF_POS = &H4
Private Const SIF_ALL = (SIF_RANGE Or SIF_PAGE Or SIF_POS)
Private Const SB_CTL = 2
Private Const SB_VERT = 2
Private Const SB_HORZ = 1
Private Const LOGPIXELSX = 88
' Formulaire
Private Form_Scroll As Form
' Collection contenant les contrôles à figer
Private Fixe_Ctrl As New Collection
' Structure pour API
Private Type ScrollInfo
cbSize As Long
fMask As Long
nMin As Long
nMax As Long
nPage As Long
nPos As Long
nTrackPos As Long
End Type
Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type
'Déclarations d'API
Private Declare Function GetScrollInfo Lib "user32" (ByVal hwnd As Long, ByVal fnBar As Integer, lpsi As ScrollInfo) As Boolean
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpWindowText As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetDlgCtrlID Lib "user32" (ByVal hwnd As Long) As Long
' Handle de la barre de defilement
Private Function GetScrollBarHwnd(ByVal FormhWnd As Long, ByVal BarType As Long) As Long
Dim lRet As Long
Dim lClassName As String
Dim lWindowText As String
Dim CurrenthWnd As Long
CurrenthWnd = GetWindow(FormhWnd, GW_CHILD)
Do Until CurrenthWnd = 0
Call GetScrollBarHwnd(CurrenthWnd, BarType)
lClassName = Space(255)
lRet = GetClassName(CurrenthWnd, lClassName, 255)
lClassName = left(lClassName, lRet)
If lClassName = "Scrollbar" Or lClassName = "NUIScrollbar" Then
If Val(SysCmd(acSysCmdAccessVer)) = 12 Then
lWindowText = Space(255)
lRet = GetWindowText(CurrenthWnd, lWindowText, 255)
lWindowText = left(lWindowText, lRet)
If lWindowText = "Horizontal" Then
lRet = SB_HORZ
ElseIf lWindowText = "Vertical" Then
lRet = SB_VERT
End If
Else
lRet = GetDlgCtrlID(CurrenthWnd)
End If
If lRet = BarType Then
GetScrollBarHwnd = CurrenthWnd
Exit Function
End If
End If
CurrenthWnd = GetWindow(CurrenthWnd, GW_HWNDNEXT)
Loop
End Function
' Convertir les twips en pixels pour les APIs
Private Function PixelToTwips(X As Long) As Long
Static mult As Long
Dim hDC As Long
If mult = 0 Then
hDC = GetDC(0)
mult = 1440 / GetDeviceCaps(hDC, LOGPIXELSX)
ReleaseDC 0, hDC
End If
PixelToTwips = X * mult
End Function
Private Sub Class_Terminate()
Set Form_Scroll = Nothing
End Sub
' Sur événement du Timer
Public Sub Form_scroll_Timer()
Static pos As Long ' Ancienne position de la barre horizontale
Static hwnd As Long ' Handle de la barre horizontale
Dim lFormParent As String ' Nom du parent d'un sous-formulaire
' Recherche le nom d'un éventuel parent du formulaire
On Error Resume Next
lFormParent = Form_Scroll.Parent.Name
On Error GoTo fin ' Ne pas continuer si pas de formulaire actif
If Screen.ActiveForm.Name = Form_Scroll.Name Or Screen.ActiveForm.Name = lFormParent Then
' Si formulaire actif = le formulaire à traiter
On Error GoTo 0
If hwnd = 0 Then hwnd = GetScrollBarHwnd(Form_Scroll.hwnd, SB_HORZ)
pos = ScrollForm(hwnd, pos)
End If
fin:
End Sub
'Déplace les colonnes fixes
Private Function ScrollForm(ByVal hwnd As Long, oldpos As Long) As Double
Dim ctrl As Control
Dim SI As ScrollInfo
Dim delta As Long
Dim max_col As Double
Dim lngret As Long
Dim tabindex As Double
Dim NameCtrl As Variant
' Lit les infos de l'ascenseur horizontal
SI.cbSize = Len(SI)
SI.fMask = SIF_ALL
lngret = GetScrollInfo(hwnd, SB_CTL, SI)
delta = PixelToTwips(SI.nPos) - oldpos
' Si on a pas bougé on sort
If delta = 0 Then GoTo fin
' Recherche du contrôle figé le plus à droite de la section détail
For Each ctrl In Form_Scroll.Section(acDetail).Controls
On Error Resume Next
NameCtrl = Fixe_Ctrl.Item(ctrl.Name)
If Err.Number = 0 Then
max_col = IIf(ctrl.left + ctrl.Width + delta > max_col, ctrl.left + ctrl.Width + delta, max_col)
End If
On Error GoTo 0
Next
' Déplace le focus sur le premier contrôle visible (dans la section détail)
' si le focus était sur un contrôle qui devient invisible
On Error Resume Next
If Form_Scroll.ActiveControl.left < max_col Then
NameCtrl = Fixe_Ctrl.Item(Form_Scroll.ActiveControl.Name)
If Err.Number <> 0 Then
tabindex = Val(Form_Scroll.ActiveControl.tabindex)
NameCtrl = ""
For Each ctrl In Form_Scroll.Section(acDetail).Controls
On Error Resume Next
If ctrl.tabindex > tabindex And ctrl.left > max_col Then
If Err.Number = 0 Then ' Si la propriété tabindex existe
If NameCtrl = "" Then
NameCtrl = ctrl.Name
ElseIf ctrl.left < Form_Scroll.Controls(NameCtrl).left Then
NameCtrl = ctrl.Name
End If
End If
End If
Next
Form_Scroll.Controls(NameCtrl).SetFocus
End If
End If
' Déplace les contrôles pour les rendres "fixes"
For Each NameCtrl In Fixe_Ctrl
Form_Scroll.Controls(NameCtrl).left = Form_Scroll.Controls(NameCtrl).left + delta
Next
On Error GoTo 0
fin:
' Renvoie la position de l'ascenseur
ScrollForm = PixelToTwips(SI.nPos)
End Function
' Initialisation
Public Sub Initialize(pForm As Access.Form)
Dim ctrl As Control
' Formulaire
Set Form_Scroll = pForm
' Ajoute les contrôles contenant <fixe> dans la remarque
' dans la collection de contrôles à figer
For Each ctrl In Form_Scroll.Controls
If ctrl.Tag Like "*FixeCtrl*" Then
Fixe_Ctrl.Add ctrl.Name, ctrl.Name
End If
Next
End Sub
' Ajoute un contrôle fixe à la collection
Public Sub Fixe_Control(ctrl As String)
On Error Resume Next
Fixe_Ctrl.Add ctrl, ctrl
End Sub
' Retire un contrôle fixe à la collection
Public Sub CancelFixe_Control(ctrl As String)
On Error Resume Next
Fixe_Ctrl.Remove ctrl
End Sub |
Partager