Tekst informacyjny o polityce Cookies Close   
    
 
         
• Strona główna
• 1. Linki
• 3. Kontakt: e-Mail
 
         
• 1. Baza danych
• 2. Tabele i kwerendy
• 3. Formularze
• 4. Raporty
• 5. Moduły i makra
• 6. Obsługa błędów
 
    

II.   VBA 

    
• 1. Okna Accessa
• 2. Okna Formularzy
• 3.Okna Dialogowe
• 4. Tekst
• 5. Liczby
• 6. Pliki
• 7. Inne
 
    

III.   API 

    
• 1. Ogólnie o API
• 2. Funkcje API
• 3. System
• 4. Praca z oknami
• 5. Okna dialogowe
• 6. API - Inne
 
         
• 1. Bitmapy 24 Bit
• 2. GDI i HDC
• 3. Kody kreskowe
• 4. Formant Image
• 5. FreeImage.dll
 
    

V.   Inne 

    
• 1. Shell i MsDOS
• 2. Kontrolki
• 3. ६ԼҚ ਸ
• 4. Unikod

 
Odwiedzin:

Logo AccessFAQ• II.1. VBA - Okna MS Access [1] •

1.1 Jak pobrać uchwyty, klasę, tytuł oraz ID wszystkich okien MS Access ?
1.2 Jak pokazać (ukryć) okno bazy danych przy pomocy API ?
1.3 Jak zdezaktwować okno bazy danych ?
1.4 Jak sprawdzić, czy okno bazy danych jest widoczne ?
1.5 Jak zdezaktywować (ukryć) menu systemowe oraz przyciski Min, Max oraz X ?
1.6 Jak zdezaktywować przycisk X na pasku tytułowym okna MS Access ?
1.7 Jak uruchomić wbudowany pasek postępu MS Access ?
1.8 Jak powiększyć wbudowany wskaźnik postępu MS Access ?
1.9 Jak zmienić kolor tła aplikacji Access ?
<<• idź do str. 2 •>>
 

1.1 Jak pobrać uchwyty, klasę, tytuł oraz ID wszystkich okien MS Access ?

Private Declare Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal Msg As Long, _
wParam As Any, _
lParam As Any) As Long
Private Const WM_GETTEXTLENGTH = &HE
Private Const WM_GETTEXT = &HD
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 GetDlgCtrlID Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5



' • Tworzy listę wszystkich okien i okien potomnych (dzieci) począwszy od okna hWind.
' • korzysta z funkcji z przykładów ze strony "Praca z oknami"
' • Funkcja wywoływana jest rekurencyjnie.
' • f As Byte, j As Integer - utworzono dla potrzeb prawidłowego wyświetlania danych.



Private Function zbInfoChild(hWind As Long, sSep As String, _
f As Byte, j As Integer) As String
Dim sHwnd As String * 5
Dim sClass As String * 40
Dim sTxtWnd As String * 25
Dim sID As String * 10
Dim hNext As Long
Dim lRet As Long
Dim i As Integer
Static sRet As String

If f = False Then
' drukuj nagłówek tabelki
sRet = String(94, Asc("=")) & vbNewLine
sHwnd = " hwnd"
sClass = Space(13) & "Klasa okna"
sTxtWnd = Space(7) & "Tekst okna"
sID = " ID "
sRet = sRet & "| Lp." & " |" & _
sHwnd & " |" & _
sClass & "|" & _
sTxtWnd & "|" & _
sID & " |" & vbNewLine

sRet = sRet & String(94, Asc("=")) & vbNewLine

sHwnd = hWind
sClass = zbGetClassName(hWind)
sTxtWnd = zbGetTextWind_2(hWind)
sID = zbGetIDWind(hWind)

sClass = sSep & Format(i, "00") & ". " & sClass
sRet = sRet & "| " & Format(j, "000") & " | " & _
sHwnd & "|" & _
sClass & "|" & _
sTxtWnd & "| " & _
sID & " |" & vbNewLine
End If

f = True

' pobierz uchwyt pierwszego dziecka
hNext = GetWindow(hWind, GW_CHILD)
' wykonaj dla wszystkich dzieci
Do Until hNext = 0
i = i + 1 ' pomocniczy licznik okien Child
j = j + 1 ' Lp.
sHwnd = hNext
sClass = zbGetClassName(hNext)
sTxtWnd = zbGetTextWind_2(hNext)
sID = zbGetIDWind(hNext)

sClass = sSep & Format(i, "00") & ". " & sClass
sRet = sRet & "| " & Format(j, "000") & " | " & _
sHwnd & "|" & _
sClass & "|" & _
sTxtWnd & "| " & _
sID & " |" & vbNewLine

' nie ma okna Child
If GetWindow(hNext, GW_CHILD) = 0 Then
Else
Call zbInfoChild(hNext, sSep & " ", f, j)
End If
' pobierz uchwyt następnego dziecka
hNext = GetWindow(hNext, GW_HWNDNEXT)
Loop

zbInfoChild = sRet

End Function


' zwraca tytuł (tekst) okna
Private Function zbGetTextWind_2(hWind As Long) As String
Dim sBff As String
Dim lLen As Long
Dim lRet As Long

' pobierz długość tekstu
lLen = SendMessage(hWind, WM_GETTEXTLENGTH, _
ByVal 0&, ByVal 0&) + 1&
' przygotuj buffor na tekst
sBff = String(lLen, vbNullChar)
' pobierz tytuł i zwróć długość pobranego tekstu
lRet = SendMessage(hWind, WM_GETTEXT, _
ByVal lLen, ByVal sBff)

zbGetTextWind_2 = Left$(sBff, lRet)

End Function


' zwraca nazwę klasy okna
Private Function zbGetClassName(hWind As Long) As String
Dim lRet As Long
Dim sBff As String
Const MY_SIZEBUFFER As Long = 256

sBff = String(MY_SIZEBUFFER, vbNullChar)
lRet = GetClassName(hWind, sBff, MY_SIZEBUFFER)
zbGetClassName = Left$(sBff, lRet)

End Function


' zwraca Identyfikator okna o uchwycie hWind, lub ZERO
Private Function zbGetIDWind(hWind As Long) As Long
zbGetIDWind = GetDlgCtrlID(hWind)
End Function


' przykładowe wywołanie:
Private Sub btnTest_Click()
Debug.Print zbInfoChild(Application.hWndAccessApp, "", _
False, 0); String(94, Asc("="))
DoCmd.RunCommand acCmdDebugWindow
End Sub

 ΔΔΔ 

 

1.2 Jak pokazać (ukryć) okno bazy danych przy pomocy API ?

Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal nCmdShow As Long) As Long
Private Declare Function BringWindowToTop Lib "user32" _
(ByVal hwnd As Long) As Long
Private Const SW_HIDE = 0&
Private Const SW_SHOWNORMAL = 1&
Private Const MY_CLASS_DB As String = "ODb"
Private Const MY_CLASS_MDI As String = "MDIClient"


Private Sub zbShowDbAPI(fVisible As Boolean)
Dim hDB As Long

hDB = FindWindowEx(Application.hWndAccessApp, 0&, _
MY_CLASS_MDI, vbNullString)
If hDB = 0 Then Exit Sub
hDB = FindWindowEx(hDB, 0&, MY_CLASS_DB, vbNullString)
If hDB = 0 Then Exit Sub

If fVisible = True Then
Call ShowWindow(hDB, SW_SHOWNORMAL)
Call BringWindowToTop(hDB)
Else
Call ShowWindow(hDB, SW_HIDE)
End If

End Sub

 ΔΔΔ 

 

1.3 Jak zdeaktywować okno bazy danych ?

Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function EnableWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal fEnable As Long) As Long
Private Declare Function GetParent Lib "user32" _
(ByVal hwnd As Long) As Long
Private Const MY_CLASS_DB As String = "ODb"


Private Sub zbEnableDB(fEnable As Boolean)
Dim hDB As Long
Dim hTmp As Long

hDB = FindWindowEx(GetParent(Me.hwnd), 0&, _
MY_CLASS_DB, vbNullString)
If hDB = 0 Then Exit Sub
EnableWindow hDB, fEnable
Application.CommandBars("Database TitleBar").Enabled = fEnable

' ponieważ wywołanie np. okna MsgBox powoduje odblokowanie okna bazy, musimy zdeaktywować wszystkie potomne okna (dzieci) właściwego okna bazy, aby uczynić nasze okno bazy niedostępnym dla użytkownika

Do
hTmp = FindWindowEx(hDB, hTmp, vbNullString, vbNullString)
If hTmp = 0 Then Exit Do
EnableWindow hTmp, fEnable
Loop

End Sub

 ΔΔΔ 

 

1.4 Jak sprawdzić, czy okno bazy danych jest widoczne ?

Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function GetParent Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function IsWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function IsWindowVisible Lib "user32" _
(ByVal hwnd As Long) As Long
Private Const MY_CLASS_DB As String = "ODb"


Private Function zbIsVisibleDB() As Boolean
zbIsVisibleDB = IsWindowVisible( _
FindWindowEx(GetParent(Me.hwnd), _
0&, MY_CLASS_DB, vbNullString))
End Function

 ΔΔΔ 

 

1.5 Jak zdeaktywować (ukryć) menu systemowe oraz przyciski Min, Max oraz X ?

Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Const GWL_STYLE = (-16)
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal Msg As Long, _
wParam As Any, _
lParam As Any) As Long
Private Const WM_NCPAINT As Long = &H85
' pierwotny styl okna Access'a
Private lOldStyle As Long
' wartości parametru lBox procedury zbHideSysBox (...)
Private Const WS_SYSMENU = &H80000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_MAXIMIZEBOX = &H10000
Private Const MY_MAXMINBOX = _
(WS_MINIMIZEBOX Or WS_MAXIMIZEBOX)


Private Sub zbHideSysBox(lBox As Long, hWind As Long, fHide As Boolean)

Select Case lBox
Case WS_SYSMENU   ' ukryj (pokaż) menu systemowe
zbRemoveSysBox lBox, hWind, fHide

Case WS_MINIMIZEBOX   'ukryj (pokaż) przycisk MIN
zbRemoveSysBox lBox, hWind, fHide

Case WS_MAXIMIZEBOX   ' ukryj (pokaż) przycisk MAX
zbRemoveSysBox lBox, hWind, fHide

Case MY_MAXMINBOX   ' ukryj (pokaż) przycisk MIN i MAX
zbRemoveSysBox lBox, hWind, fHide
End Select

End Sub


Private Sub zbRemoveSysBox(lBox As Long, _
ByVal hWind As Long, _
fRemove As Boolean)
Dim lNewStyle As Long

' zapamiętaj styl okna Access'a
If lOldStyle = 0 Then
lOldStyle = GetWindowLong(hWind, GWL_STYLE)
End If

If fRemove Then
lNewStyle = SetWindowLong(hWind, GWL_STYLE, _
lOldStyle And (Not lBox))
Else
lNewStyle = SetWindowLong(hWind, GWL_STYLE, _
lOldStyle Or lBox)
End If

SendMessage hWind, WM_NCPAINT, ByVal 1&, ByVal 0&

End Sub


' przykładowe wywołanie:
Private Sub btnTest_Click()

    ' ukryj (deaktywuj)
zbHideSysBox WS_SYSMENU, Application.hWndAccessApp, True
' pokaż (aktywuj)
' zbHideSysBox WS_SYSMENU, Application.hWndAccessApp, False

End Sub

 ΔΔΔ 

 

1.6 Jak zdeaktywować przycisk X na pasku tytułowym okna MS Access ?

• Niestety deaktywacja przycisku X nie zabezpiecza nas przed zamknięciem bazy kombinacją klawiszy Alt+F4


Private Declare Function DrawMenuBar Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function GetSystemMenu Lib "user32" _
(ByVal hwnd As Long, _
ByVal bRevert As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" _
(ByVal hAcc As Long) As Long
Private Declare Function EnableMenuItem Lib "user32" _
(ByVal hAcc As Long, _
ByVal wIDEnableItem As Long, _
ByVal wEnable As Long) As Long
Private Const MF_BYPOSITION = &H400
Private Const MF_DISABLED = &H2
Private Const MF_GRAYED = &H1
Private Declare Function SetWindowPos Lib "user32" _
(ByVal hwnd As Long, _
ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, _
ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOZORDER = &H4
Private Const SWP_FRAMECHANGED = &H20


Private Sub zbEnableX(hWind As Long, fEnabled As Boolean)
Dim hSysMnu As Long
Dim lCountMnu As Long
Const MY_POS As Long = 1

hSysMnu = GetSystemMenu(hWind, False)

If hSysMnu <> 0 Then
lCountMnu = GetMenuItemCount(hSysMnu)
If fEnabled Then
EnableMenuItem hSysMnu, lCountMnu - MY_POS, _
MF_BYPOSITION And Not _
(MF_DISABLED Or MF_GRAYED)
Else
EnableMenuItem hSysMnu, lCountMnu - MY_POS, _
MF_BYPOSITION Or _
(MF_DISABLED Or MF_GRAYED)
End If
DrawMenuBar hSysMnu
End If
' wymuś odswieżenie okna
Call SetWindowPos(hWind, 0&, 0&, 0&, 0&, 0&, _
SWP_NOSIZE Or SWP_NOMOVE Or _
SWP_FRAMECHANGED Or SWP_NOZORDER)

End Sub


' przykładowe wywołanie:
Private Sub btnTest_Click()

' deaktywuj przycisk X
zbEnableX Application.hWndAccessApp, False
' ew. tylko dla formularza PopUp
' zbEnableX Me.hwnd, False

End Sub

 ΔΔΔ 

 

1.7 Jak uruchomić wbudowany pasek postępu MS Access ?

Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)


Private Sub zbAccProgBar(sTextStatBar As String, _
lStart As Long, lEnd As Long)
Dim fStatBarVisible As Boolean
Dim i As Long

    ' pobierz stan paska stanu (czy jest widoczny)
    fStatBarVisible = Application.GetOption("Show Status Bar")
    ' pokaż pasek stanu
    If Not fStatBarVisible Then
Application.SetOption ("Show Status Bar"), True
    End If

' zainicjuj wskaźnik postępu
    Application.SysCmd acSysCmdInitMeter, sTextStatBar, lEnd

    For i = lStart + 1 To lEnd
' aktualizuj wskaźnik postępu
Application.SysCmd acSysCmdUpdateMeter, i
' opóźnij w celach poglądowych
Sleep 10&
DoEvents
    Next

    ' usuń wskaźnik postępu
    Application.SysCmd acSysCmdRemoveMeter
    ' przywróć początkowy stan paska stanu
    Application.SetOption ("Show Status Bar"), fStatBarVisible

End Sub


' przykładowe wywołanie:
Private Sub btnTest_Click()
    Call zbAccProgBar("Standard ProgressBar", 0, 250)
End Sub

 ΔΔΔ 

 

1.8 Jak powiększyć wbudowany wskaźnik postępu MS Access ?


   Przykład:  • vba10a_08  •  52 KB  •  status: FREE  Pobrano    razy   


Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Long, _
lpRect As RECT) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function MoveWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal bRepaint As Long) As Long
Private Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal nCmdShow As Long) As Long
Private Const SW_RESTORE = 9
Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
Private hStatProg As Long
Private rctStatProg As RECT
Private fStatBarVisible As Boolean


' inicjalizacja wskaźnika postępu,
' minimalna wielkość wskaźnika = 16 pix, maksymalna ~ 62 pix

Private Sub zbIniProgBar(ByVal sTitleProgBar As String, _
lMax As Long, lSizeProgBar As Long)
Dim hStaBar As Long
Dim rctTmp As RECT
Dim i As Long
Dim lWidth As Long

' pobierz stan paska stanu (czy jest widoczny)
fStatBarVisible = Application.GetOption("Show Status Bar")
' pokaż pasek stanu jeśli nie jest widoczny
If Not fStatBarVisible Then
Application.SetOption ("Show Status Bar"), True
End If

' szukaj wskaźnika postępu
hStaBar = FindWindowEx(Application.hWndAccessApp, _
ByVal 0&, "OStatbar", vbNullString)
ShowWindow hStaBar, SW_RESTORE
hStatProg = FindWindowEx(hStaBar, ByVal 0&, _
"OStatProg", vbNullString)

' pobierz wymiary wskaźnika postępu
GetWindowRect hStatProg, rctStatProg

' minimalna wysokość wskaźnika postępu = 16
If lSizeProgBar < 26 Then
If lSizeProgBar < 16 Then lSizeProgBar = 16
rctTmp = rctStatProg
lWidth = rctStatProg.Right - rctStatProg.Left
Else
'przy wielkości > 26 tekst nie będzie widoczny
sTitleProgBar = " "
' sprawdź, czy długość paska nie będzie większa
' od szerokości okna Accessa

GetWindowRect Application.hWndAccessApp, rctTmp
lWidth = rctTmp.Right - rctTmp.Left
' doświadczalne współczynniki powiększania
If 20 * (lSizeProgBar - 14) + 65 > lWidth Then
lSizeProgBar = (14 + (lWidth - 65) / 20) - 1
End If
End If

Application.SysCmd acSysCmdInitMeter, sTitleProgBar, lMax

' ustaw wielkość i położenie wskaźnika postępu
MoveWindow hStatProg, 0&, 0&, lWidth, lSizeProgBar, True

End Sub


' aktualizuj pasek postępu
Private Sub zbUpdateProgBar(lValueProgBar As Long)
    Application.SysCmd acSysCmdUpdateMeter, lValueProgBar
End Sub


' usuń pasek postępu i przywróć jego oryginalne parametry
Private Sub zbRemoveProgBar()

' przywróć wielkość i położenie wskaźnika postępu
With rctStatProg
MoveWindow hStatProg, 0, 0, .Right - .Left, .Bottom - .Top, True
End With
' usuń wskaźnik postępu
Application.SysCmd acSysCmdRemoveMeter
' przywróć początkowy stan paska stanu
Application.SetOption ("Show Status Bar"), fStatBarVisible

End Sub


' przykładowe wywołanie:
Private Sub btnTest_Click()
Dim i As Long
Const MY_MAX_FOR As Long = 250
Const MY_SIZE_1 As Long = 25
Const MY_SIZE_2 As Long = 62

' dowolny argument lSizeProgBar
' - w zbProgBar wartość zostanie poprawiona

Call zbIniProgBar("Pasek postępu: 25 pix", _
MY_MAX_FOR, MY_SIZE_1)
For i = 0 To MY_MAX_FOR
SysCmd acSysCmdUpdateMeter, i
' opóźnij w celach poglądowych
Sleep 10&
DoEvents
Next
Call zbRemoveProgBar

Call zbIniProgBar("Duży rozmiar - tekst będzie niewidoczny", _
MY_MAX_FOR, MY_SIZE_2)
For i = 0 To MY_MAX_FOR
Call zbUpdateProgBar(i)
' opóźnij w celach poglądowych
Sleep 10&
DoEvents
Next

Call zbRemoveProgBar

End Sub

 ΔΔΔ 

 

1.9 Jak zmienić kolor tła aplikacji Access ?

Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Long, _
lpRect As RECT) As Long
Private Declare Function InvalidateRect Lib "user32" _
(ByVal hwnd As Long, _
lpRect As RECT, _
ByVal bErase As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetParent Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" _
(ByVal crColor As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
(ByVal hObject As Long) As Long
Private Declare Function SetClassLong Lib "user32" _
Alias "SetClassLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Const GCL_HBRBACKGROUND = (-10)
Private Declare Function GetSysColor Lib "user32" _
(ByVal nIndex As Long) As Long
Private Const COLOR_APPWORKSPACE = 12


Private Sub zbSetMDIBackColor(ByVal lBkgColor As Long)
Dim hBrushNew As Long
Dim hBrushOld As Long
Dim hMDI As Long
Dim rct As RECT

' utwórz nowy pędzel
hBrushNew = CreateSolidBrush(lBkgColor)
' pobierz uchwyt okna MDI
hMDI = GetParent(Me.hwnd)
' pobierz wymiary okna MDI
Call GetWindowRect(hMDI, rct)
rct.Top = 0:    rct.Left = 0
' ustaw nowy pędzel tła dla okna MDI
hBrushOld = SetClassLong(hMDI, _
    GCL_HBRBACKGROUND, hBrushNew)
' wymuś odświeżanie
Call InvalidateRect(hMDI, rct, 1&)
' usuń stary pędzel
Call DeleteObject(hBrushOld)

End Sub


Private Sub btnTest_Click()
    ' ustaw kolor tła aplikcji
    Call zbSetMDIBackColor(vbRed)
    ' przywróć systemowy kolor tła aplikcji
    ' Call zbSetMDIBackColor(GetSysColor( _
COLOR_APPWORKSPACE))

End Sub

 ΔΔΔ