Banner Access
Tekst informacyjny o polityce Cookies Close   

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