W jaki sposób zastąpić metodę Application.Echo False
w przypadku, gdy jest otwierane i ukrywane okno dialogowe Accessa.
Aby zapobiec odświeżaniu okien (tzw. migotaniu okien) najczęściej wywołujemy w Accesie metodę Application.Echo False.
Czasami skutkuje niestosowanie funkcji DoEvents przekazującej sterowanie do systemu operacyjnego w celu przetworzenia wszystkich zdarzeń z systemowej kolejki.
W przypadku, gdy chcemy operować na oknach dialogowych Accessa np. w celu odczytania z nich pewnych danych, wymienione wyżej sposoby nie działają.
Sterowanie chwilowo przejmuje system, czemu towarzyszy nieprzyjemne "miganie" okna (okien) związane z odświeżeniem (przemalowaniem) okien.
Blokada odświeżania okien przez wysłanie komunikatu:
SendMessage hDsk, WM_SETREDRAW, ByVal False, ByVal 0&
Przykładowo - klasyczne otwarcie okna dialogowego "Drukuj" tylko w celu odczytania zainstalowanych drukarek zastosowane w przykładzie "Lista drukarek"
- W tym celu deklarujemy funkcję API zwracającą uchwyt Pulpitu (Desktop Window:
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Sub btnNoRedraw_Click()
On Error GoTo Err_btnNoRedraw_Click
hDsk = GetDesktopWindow
' uruchom Timer formularza
Me.TimerInterval = 50
' blokada odświeżania okien
SendMessage hDsk, WM_SETREDRAW, ByVal False, ByVal 0&
On Error Resume Next
-
' otwórz okno dialogowe (Timer jest już uruchomiony)
DoCmd.RunCommand acCmdPrint
If Err.Number <> 0 Then Err.Clear
- On Error GoTo Err_btnNoRedraw_Click
' blokada odświeżania okien - okno dialogowe zostało zamknięte
SendMessage hDsk, WM_SETREDRAW, ByVal True, ByVal 0&
Exit_btnNoRedraw_Click:
- Exit Sub
- Err_btnNoRedraw_Click:
- ' Na wszelki wypadek !!!
SendMessage hDsk, WM_SETREDRAW, ByVal True, ByVal 0&
MsgBox Err.Description
Resume Exit_btnNoRedraw_Click
- End Sub
- A w Timerze formularza wykonujemy zamierzone operacje
Private Sub Form_Timer()
Dim hWind as Long
- Me.TimerInterval = 0
hWind = GetFocus
.........
.........
.........
' po wykonaniu wszystkich czynności zamykamy okno dialogowe "Drukuj"
SendMessage GetParent(hWind), WM_CLOSE, 0&, 0&
- End Sub
Niestety, pomimo że funkcja:
SendMessage hDsk, WM_SETREDRAW, ByVal True, ByVal 0&
sprawuje się dość dobrze w przypadku otwierania okien dialogowych Accessa, to nie nadaje się bezpośrednio do zastosowania do wszystkich okien Accessa.
Blokada odświeżania okien za pomocą funkcji API: LockWindowUpdate
- Zdecydowanie lepiej jest korzystać z funkcji:
Private Declare Function LockWindowUpdate Lib "user32" _
- (ByVal hwndLock As Long) As Long
- Blokuje rysowanie (odświeżanie okna) hwndLock, przy powodzeniu zwraca wartość <> 0.
lhwndLock
- uchwyt okna dla którego funkcja przemalowywania będzie nieaktywna
Dla wartości parametru = Null (FALSE) funkcja przemalowywania zostaje uaktywniona
Można zablokować jednorazowo tylko jedno okno.
Po niewielkich przeróbkach polegającyvh tylko na zamianie obu funkcji nasza procedura będzie miała postać:
Private Sub btnLockUpdt_Click()
On Error GoTo Err_btnLockUpdt_Click
hDsk = GetDesktopWindow
' uruchom Timer formularza
Me.TimerInterval = 50
' blokada odświeżania okien
LockWindowUpdate hDsk
On Error Resume Next
-
' otwórz okno dialogowe (Timer jest już uruchomiony)
DoCmd.RunCommand acCmdPrint
If Err.Number <> 0 Then Err.Clear
- On Error GoTo Err_btnLockUpdt_Click
' odblokuj odświeżanie okien - okno dialogowe zostało zamknięte
LockWindowUpdate False
Exit_btnLockUpdt_Click:
- Exit Sub
- Err_btnNoRedraw_Click:
- ' Na wszelki wypadek !!!
LockWindowUpdate False
MsgBox Err.Description
Resume Exit_btnLockUpdt_Click
- End Sub