Access

  MS Access 2010+  |  Formularze  |   VBA 7.0

• Pasek przewijania.

Pasek przewijania (scrollbar) to formant służący najczęściej do przesuwania zawartości okna, która jest większa, niż powierzchnia przewidziana do wyświetlania jego zawartości. W zdecydowany sposób ułatwia poruszanie się wewnątrz tego obszaru. Jeśli formularz zawiera więcej pól, niż można wyświetlić w jego roboczym obszarze, zazwyczaj pojawia się pionowy i (lub) poziomy pasek przewijania umożliwiający szybkie przemieszczanie się między rekordami.

Paski przewijania okna formularza.

Chcąc programowo zmienić położenie formantów formularza, a zwłaszcza jeżeli chcemy formant ten dosunąć do prawej lub dolnej krawędzi okna musimy wiedzieć, czy paski przewijania są widoczne. Gdy pasek postępu jest widoczny, formant powinniśmy dosunąć prawą (lub dolną) krawędzią do paska przewijania, a nie do krawędzi okna formularza, gdyż wtedy pasek przewijania częściowo zasłoni przesuwany formant.

Paski przewijania w MS Access
Poziomy pasek przewijania zasłania Przyciski nawigacyjne

Wzorując się na przykładzie Paski przewijania Access i opisanej tam funkcji accScrollBars(...) powinniśmy pobrać styl okna formularza za pomocą funkcji GetWindowLong(...):

  lWindowStyle = GetWindowLong(Me.hwnd, GWL_STYLE)  

i korzystając z operatora bitowego AND sprawdzić, czy widoczny jest poziomy i pionowy pasek przewijania

If (lWindowStyle AND WS_HSCROLL) = WS_HSCROLL Then ' jest poziomy pasek przewijania

If (lWindowStyle AND WS_VSCROLL) = WS_VSCROLL Then ' jest pionowy pasek przewijania

Niestety, metoda ta nie sprawdza się w przypadku okien formularza. Zwracana wartość lWindowStyle nie zawiera stylu WS_HSCROLL ani WS_VSCROLLzawsze uzyskamy wynik, że żaden pasek przewijania nie jest widoczny w oknie formularza.

Brak pasków przewijania w formularzu
Paski przewijania okna formularza nie są identyfikowane.

Różnice pomiędzy oknem roboczym MS Access, a oknem formularza.

Aby wychwycić różnice pomiędzy oknami, musimy najechać myszką na pasek przewijania okna roboczego MS Access i odczytać za pomocą funkcji API jakie okno znajduje się pod kursorem myszy.

Paski przewijania okna MS Access
Poziomy i pionowy pasek przewijania okna roboczego MS Access

Istotne informacje to takie, że okno robocze MS Access jest oknem klasy „MDIClient”. Styl tego okna określa, że jest oknem potomnym (WS_CHILD) z widocznymi oboma paskami przewijania WS_HSCROLLWS_VSCROLL. Oknem nadrzędnym jest okno „OMain”. Reszta danych nie wnosi nic istotnego do problemów widoczności pasków formularza.

 

Paski przewijania w MS Access
Poziomy i pionowy pasek przewijania okna formularza

Już na pierwszy rzut oka widać, że okno formularza, to zupełnie inna „bajka” . Okno robocze „MDIClient” (ma paski przewijania) jest oknem nadrzędnym (rodzicem) okna formularza „OForm”, które z kolei jest oknem nadrzędnym (rodzicem) okna „NUIScrollbar”, a ono posiada okno potomne (dziecko) „NetUIHWND”.
Formularz posiada dwa okna klasy „NUIScrollbar”,
   • pierwsze ma spolszczony tytuł „Poziom”,
   • drugie posiada tytuł „Pion”.
I tymi dwoma oknami zajmiemy się dokładniej. Najpierw należy znaleźć okno „NetUIHWND”. Jeżeli jesteśmy pewni, że zawsze będziemy używać wersji polskojęzycznej, to w ostatnim argumencie lpszWindow możemy zamienić wartość vbNullString na tytuł okna "Poziom":

hNUIHor = FindWindowEx(Me.hwnd, 0&, "NUIScrollbar", vbNullString)

następnie pobieramy styl okna „NetUIHWND”:

  lWindowStyle = GetWindowLong(hNUIHor, GWL_STYLE)  

i sprawdzamy, czy okno „NetUIHWND” jest widoczne:

If (lWindowStyle AND WS_VISIBLE) = WS_VISIBLE Then ' jest poziomy pasek przewijania

Czy widoczny jest pionowy i (lub) poziomy pasek przewijania formularza?

Właściwość ScrollBars formularza

Bardzo prowizoryczna i niepewna metoda, opierająca się na wykluczeniu pewnych opcji daje nam właściwość ScrollBars formularza. Poniżej przedstawiam wnioski (kolorem brązowym co można wywnioskować ze zwróconej wartości ScrollBars formularza. Więcej o właściwości ScrollBars na stronie Paski przewijania formularza i pola tekstowego

Me.ScrollBarsOpis
0 Żaden pasek przewijania nie pojawi się w formularzu.
Poziomy i pionowy pasek przewijania jest niewidoczny
1 Poziomy pasek przewijania może pojawić się w formularzu.
Pionowy pasek przewijania jest niewidoczny
2 Pionowy pasek przewijania może pojawić się w formularzu.
Poziomy pasek przewijania jest niewidoczny
3 Pionowy i poziomy pasek przewijania może pojawić się w formularzu
Poziomy i (lub) pionowy pasek przewijania może być widoczny

Praktycznie właściwości ScrollBars nie daje jednoznacznych odpowiedzi na pytanie, które paski przewijania formularza są widoczne. Pewniejsza jest informacja, które paski nie są widoczne.

Funkcja formScrollBars(hForm As Long) As Long

 

⊗ Private Function formScrollBars(hForm As Long) As Long
  • Sprawdza, które paski przewijania okna formularza o uchwycie hForm są widoczne
  • argumenty:
    • hForm
    • uchwyt okna formularza
  • zwraca:
  • Przy powodzeniu zwraca liczbę określającą, które paski przewijania są widoczne:
    • 0 - żaden pasek przewijania nie jest widoczny
    • 1 - tylko poziomy pasek przewijania jest widoczny
    • 2 - tylko pionowy pasek przewijania jest widoczny
    • 3 - pionowy i poziomy pasek przewijania są widoczne
    Przy niepowodzeniu funkcja zwraca -1
  • autor: Zbigniew Bratko
  • data: 11.01.2019
Option Compare Database
Option Explicit
 
#If Win64 Then
  Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" _
          Alias "GetWindowLongPtrA" _
          (ByVal hwnd As LongPtr, _
          ByVal nIndex As Long) As LongPtr
  Private Declare PtrSafe Function FindWindowEx Lib "user32" _
          Alias "FindWindowExA" ( _
          ByVal hWndParent As LongPtr, _
          ByVal hWndChildAfter As LongPtr, _
          ByVal lpszClass As String, _
          ByVal lpszWindow As String) As LongPtr
#ElseIf VBA7 Then
  Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" _
          Alias "GetWindowLongA" _
          (ByVal hwnd As LongPtr, _
          ByVal nIndex As Long) As LongPtr
  Private Declare PtrSafe Function FindWindowEx Lib "user32" _
          Alias "FindWindowExA" ( _
          ByVal hWndParent As LongPtr, _
          ByVal hWndChildAfter As LongPtr, _
          ByVal lpszClass As String, _
          ByVal lpszWindow As String) As LongPtr
#Else
  Private Declare Function GetWindowLong Lib "user32" _
          Alias "GetWindowLongA" _
          (ByVal hwnd As Long, _
          ByVal nIndex As Long) As Long
  Private Declare Function FindWindowEx Lib "user32" _
          Alias "FindWindowExA" ( _
          ByVal hWndParent As Long, _
          ByVal hWndChildAfter As Long, _
          ByVal lpszClass As String, _
          ByVal lpszWindow As String) As Long
#End If
 
' stała określające przesunięcie argumentu nIndex :
Private Const GWL_STYLE = (-16)       'styl okna
' stałe określające styl okna
Private Const WS_HSCROLL = &H100000   'okno posiada poziomy pasek przewijania
Private Const WS_VSCROLL = &H200000   'okno posiada pionowy pasek przewijania
Private Const WS_VISIBLE = &H10000000 'okno jest widoczne po utworzeniu

#If VBA7 Then
  Private Function formScrollBars(hForm As LongPtr) As Long
#Else
  Private Function formScrollBars(hForm As Long) As Long
#End If
 
#If VBA7 Then
	Dim lStyleHor   As LongPtr
	Dim lStyleVert  As LongPtr
	Dim hNUIHor     As LongPtr
	Dim hNUIVert    As LongPtr
#Else
	Dim lStyleHor   As Long
	Dim lStyleVert  As Long
	Dim hNUIHor     As Long
	Dim hNUIVert    As Long
#End If
Const cNUIScrollbar As String = "NUIScrollbar"

	' szukaj w formularzu pierwszego okna klasy "NUIScrollbar"
	' ewentualnie szukaj okna o spolszczonej nazwie "Poziom"
	hNUIHor = FindWindowEx(hForm, 0&, cNUIScrollbar, vbNullString)
	'hNUIHor = FindWindowEx(hForm, 0&, cNUIScrollbar, "Poziom")

	' szukaj w formularzu drugiego okna klasy "NUIScrollbar"
	' ewentualnie szukaj okna o spolszczonej nazwie "Pion"
	hNUIVert = FindWindowEx(hForm, hNUIHor, cNUIScrollbar, vbNullString)
	'hNUIVert = FindWindowEx(hForm, hNUIHor, cNUIScrollbar, "Pion")

	 If hNUIHor = 0 Or hNUIVert = 0 Then
		' coś poszło nie tak
		formScrollBars = -1
		Exit Function
	End If

	' pobierz style okien klasy "NUIScrollbar"
	#If VBA7 Then
		lStyleHor = GetWindowLongPtr(hNUIHor, GWL_STYLE)
		lStyleVert = GetWindowLongPtr(hNUIVert, GWL_STYLE)
	#Else
		lStyleHor = GetWindowLong(hNUIHor, GWL_STYLE)
		lStyleVert = GetWindowLong(hNUIVert, GWL_STYLE)
	#End If

	' porównaj bitowo style okien ze stylem WS_VISIBLE
	If ((lStyleHor And WS_VISIBLE) = WS_VISIBLE) And ((lStyleVert And WS_VISIBLE) = WS_VISIBLE) Then
		 formScrollBars = 3
	ElseIf ((lStyleVert And WS_VISIBLE) = WS_VISIBLE) Then
		 formScrollBars = 2
	ElseIf ((lStyleHor And WS_VISIBLE) = WS_VISIBLE) Then
		 formScrollBars = 1
	End If

End Function

' przykładowe wywołanie:
Private Sub btnTest_Click()
Dim lRetVal As Long

	' pobierz pseudowłaściwość ScrollBar
	lRetVal = formScrollBars(Me.hwnd)

	Select Case lRetVal
		Case 0
			MsgBox "Żaden pasek przewijania."
		Case 1
			MsgBox "Poziomy pasek przewijania."
		Case 2
			MsgBox "Pionowy pasek przewijania."
		Case 3
			MsgBox "Oba paski przewijania."
		Case Else
			MsgBox "Nieprzewidziany błąd."
		End Select
 
End Sub
Paski przewijania w formularzu
Paski przewijania okna formularza są identyfikowane.

 

Znak Uwaga Przykład ten nie będzie działał w MS Access w wersji 2003-. Spróbuj wtedy zmienić wartość stałej Const cNUIScrollbar As String = "NUIScrollbar" na "Scrollbar".

 

Pobierz    Do pobrania:Paski przewijania w oknie formularza pobrano () razy