Option _Explicit

Const TDCBF_OK_BUTTON = &H1
Const TDCBF_YES_BUTTON = &H2
Const TDCBF_NO_BUTTON = &H4
Const TDCBF_CANCEL_BUTTON = &H8
Const TDCBF_RETRY_BUTTON = &H10
Const TDCBF_CLOSE_BUTTON = &H20

Const IDCANCEL = 2
Const IDNO = 7
Const IDOK = 1
Const IDRETRY = 4
Const IDYES = 6

Const TDF_ENABLE_HYPERLINKS = &H1
Const TDF_USE_HICON_MAIN = &H2
Const TDF_USE_HICON_FOOTER = &H4
Const TDF_ALLOW_DIALOG_CANCELLATION = &H8
Const TDF_USE_COMMAND_LINKS = &H10
Const TDF_USE_COMMAND_LINKS_NO_ICON = &H20
Const TDF_EXPAND_FOOTER_AREA = &H40
Const TDF_EXPANDED_BY_DEFAULT = &H80
Const TDF_VERIFICATION_FLAG_CHECKED = &H100
Const TDF_SHOW_PROGRESS_BAR = &H0200
Const TDF_SHOW_MARQUEE_PROGRESS_BAR = &H0400
Const TDF_CALLBACK_TIMER = &H0800
Const TDF_POSITION_RELATIVE_TO_WINDOW = &H1000
Const TDF_RTL_LAYOUT = &H2000
Const TDF_NO_DEFAULT_RADIO_BUTTON = &H4000
Const TDF_CAN_BE_MINIMIZED = &H8000
Const TDF_SIZE_TO_CONTENT = &H1000000

Const TDN_BUTTON_CLICKED = 2
Const TDN_CREATED = 0
Const TDN_DESTROYED = 5
Const TDN_DIALOG_CONSTRUCTED = 7
Const TDN_EXPANDO_BUTTON_CLICKED = 10
Const TDN_HELP = 9
Const TDN_HYPERLINK_CLICKED = 3
Const TDN_NAVIGATED = 1
Const TDN_RADIO_BUTTON_CLICKED = 6
Const TDN_TIMER = 4
Const TDN_VERIFICATION_CLICKED = 8

Const WM_USER = &H0400
Const TDM_CLICK_BUTTON = WM_USER + 102
Const TDM_CLICK_RADIO_BUTTON = WM_USER + 110
Const TDM_CLICK_VERIFICATION = WM_USER + 113
Const TDM_ENABLE_BUTTON = WM_USER + 111
Const TDM_ENABLE_RADIO_BUTTON = WM_USER + 112
Const TDM_NAVIGATE_PAGE = WM_USER + 101
Const TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = WM_USER + 115
Const TDM_SET_ELEMENT_TEXT = WM_USER + 108
Const TDM_SET_MARQUEE_PROGRESS_BAR = WM_USER + 103
Const TDM_SET_PROGRESS_BAR_MARQUEE = WM_USER + 107
Const TDM_SET_PROGRESS_BAR_POS = WM_USER + 106
Const TDM_SET_PROGRESS_BAR_RANGE = WM_USER + 105
Const TDM_SET_PROGRESS_BAR_STATE = WM_USER + 104
Const TDM_UPDATE_ELEMENT_TEXT = WM_USER + 114
Const TDM_UPDATE_ICON = WM_USER + 116

Const TDE_CONTENT = 0
Const TDE_EXPANDED_INFORMATION = 1
Const TDE_FOOTER = 2
Const TDE_MAIN_INSTRUCTION = 3

Const TDIE_ICON_MAIN = 0
Const TDIE_ICON_FOOTER = 1

Type TASKDIALOG_BUTTON
    As Long nButtonID
    As _Offset pszButtonText
End Type

Type TASKDIALOGCONFIG
    As _Unsigned Long cbSize
    As _Offset hwndParent, hInstance
    As Long dwFlags, dwCommonButtons
    As _Offset pszWindowTitle, pszMainIcon, pszMainInstruction, pszContent
    As _Unsigned Long cButtons
    As _Offset pButtons
    As Long nDefaultButton
    As _Unsigned Long cRadioButtons
    As _Offset pRadioButtons
    As Long nDefaultRadioButton
    As _Offset pszVerificationText, pszExpandedInformation, pszExpandedControlText, pszCollapsedControlText, pszFooterIcon, pszFooter, pfCallback, lpCallbackData
    As _Unsigned Long cxWidth
End Type

Declare Dynamic Library "Comctl32"
    'Function TaskDialog%& (ByVal hwndOwner As _Offset, Byval hInstance As _Offset, pszWindowTitle As String, pszMainInstruction As String, pszContent As String, Byval dwCommonButtons As Long, Byval pszIcon As _Offset, Byval pnButton As _Offset)
    Function TaskDialogIndirect%& (ByVal pTaskConfig As _Offset, Byval pnButton As _Offset, Byval pnRadioButton As _Offset, Byval pfVerificationFlagChecked As _Offset)
End Declare

Declare Library ".\internal\c\c_compiler\x86_64-w64-mingw32\include\winerror"
    Function SUCCEEDED%% (ByVal hr As _Offset)
End Declare

Declare CustomType Library "tdicon"
    Function TD_ERROR_ICON%& Alias "task_error_icon"
    Function TD_WARNING_ICON%& Alias "task_warning_icon"
    Function TD_INFORMATION_ICON%& Alias "task_info_icon"
    Function TD_SHIELD_ICON%& Alias "task_shield_icon"
    Function TD_SEC_SHIELD_ICON%& Alias "task_sec_shield" 'TD_SEC icons have banners
    Function TD_SEC_WARN_ICON%& Alias "task_sec_warning"
    Function TD_SEC_ERROR_ICON%& Alias "task_sec_error"
    Function TD_SEC_SUCCESS_ICON%& Alias "task_sec_success"
End Declare

Declare CustomType Library "taskdlg"
    Function TaskDialogCallback%& Alias "TaskDialogCallbackProc"
End Declare

Declare CustomType Library
    Function SendMessage%& (ByVal hWnd As _Offset, Byval Msg As _Unsigned Long, Byval wParam As _Unsigned _Offset, Byval lParam As _Offset)
    Function LoadImage%& Alias "LoadImageA" (ByVal hInst As _Offset, name As String, Byval type As _Unsigned Long, Byval cx As Long, Byval cy As Long, Byval fuLoad As _Unsigned Long)
End Declare

Declare Library ".\internal\c\c_compiler\x86_64-w64-mingw32\include\shellapi"
    Function ExtractIcon%& Alias "ExtractIconA" (ByVal hInst As _Offset, pszExeFileName As String, Byval nIconIndex As _Unsigned Long)
End Declare

Declare Library
    Function MAKELPARAM%& (ByVal l As Integer, Byval h As Integer)
End Declare

'Declare CustomType Library "makeint"
'    Function MAKEINTRESOURCE%& Alias "MAKEINTRSC" (ByVal i As Long)
'End Declare

Dim As _Offset hr
Dim As Long nClickedButton

Dim As TASKDIALOGCONFIG tdconfig
Dim As TASKDIALOG_BUTTON tdbtns(0 To 1)
Dim As TASKDIALOG_BUTTON tdradio(0 To 1)

tdbtns(0).nButtonID = TDCBF_YES_BUTTON
tdbtns(1).nButtonID = TDCBF_CANCEL_BUTTON
Dim As String tdbtn1text: tdbtn1text = ANSIToUnicode("Submit" + Chr$(0))
Dim As String tdbtn2text: tdbtn2text = ANSIToUnicode("Cancel" + Chr$(0))
tdbtns(0).pszButtonText = _Offset(tdbtn1text)
tdbtns(1).pszButtonText = _Offset(tdbtn2text)

tdradio(0).nButtonID = 1
tdradio(1).nButtonID = 2
Dim As String tdradio1text: tdradio1text = ANSIToUnicode("This is radio button 1!" + Chr$(0))
Dim As String tdradio2text: tdradio2text = ANSIToUnicode("This is the second radio button" + Chr$(0))
tdradio(0).pszButtonText = _Offset(tdradio1text)
tdradio(1).pszButtonText = _Offset(tdradio2text)

tdconfig.cbSize = Len(tdconfig)
tdconfig.hwndParent = _WindowHandle
tdconfig.dwFlags = TDF_ENABLE_HYPERLINKS Or TDF_CALLBACK_TIMER Or TDF_SHOW_PROGRESS_BAR Or TDF_SHOW_MARQUEE_PROGRESS_BAR Or TDF_USE_COMMAND_LINKS Or TDF_POSITION_RELATIVE_TO_WINDOW Or TDF_USE_HICON_MAIN
tdconfig.dwCommonButtons = TDCBF_CLOSE_BUTTON
Dim As String szTitle: szTitle = ANSIToUnicode("Task Dialog Indirect Test" + Chr$(0))
tdconfig.pszWindowTitle = _Offset(szTitle)
tdconfig.pszMainIcon = ExtractIcon(0, _CWD$ + "\qb64.exe" + Chr$(0), 0) 'LoadImage(0, _CWD$ + "\source\qb64.ico" + Chr$(0), 1, 32, 32, &H00000010) 'TD_SEC_SUCCESS_ICON
Dim As String szHeader: szHeader = ANSIToUnicode("It's working!" + Chr$(0))
tdconfig.pszMainInstruction = _Offset(szHeader)
Dim As String szBodyText: szBodyText = ANSIToUnicode("Hey, look! Hyperlinks in a message box!" + Chr$(10) + "Also, custom named buttons!" + Chr$(10) + "<A HREF=" + Chr$(34) + "https://docs.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-taskdialogindirect" + Chr$(34) + ">TaskDialogIndirect MSDN Page</A>" + Chr$(0))
tdconfig.pszContent = _Offset(szBodyText)
Dim As String expanded: expanded = ANSIToUnicode("This is what shows after you expand the box!" + Chr$(0))
Dim As String expandedinfo: expandedinfo = ANSIToUnicode("This is what is contained in the expando" + Chr$(0))
Dim As String collapsed: collapsed = ANSIToUnicode("This is what you see when it is collapsed" + Chr$(0))
tdconfig.pszExpandedInformation = _Offset(expandedinfo)
tdconfig.pszExpandedControlText = _Offset(expanded)
tdconfig.pszCollapsedControlText = _Offset(collapsed)
tdconfig.cButtons = 2
tdconfig.pButtons = _Offset(tdbtns())
tdconfig.nDefaultButton = IDYES

tdconfig.cRadioButtons = 2
tdconfig.pRadioButtons = _Offset(tdradio())
tdconfig.nDefaultRadioButton = 1
Dim As String footer: footer = ANSIToUnicode("This is the text that displays in the footer" + Chr$(0))
tdconfig.pszFooter = _Offset(footer)
tdconfig.pszFooterIcon = TD_INFORMATION_ICON
Dim As String verification: verification = ANSIToUnicode("Hey, a checkbox!" + Chr$(0))
tdconfig.pszVerificationText = _Offset(verification)
tdconfig.pfCallback = TaskDialogCallback

Dim As Long checked
hr = TaskDialogIndirect(_Offset(tdconfig), _Offset(nClickedButton), 0, _Offset(checked))

If SUCCEEDED(hr) And TDCBF_YES_BUTTON = nClickedButton Then
    Print "Heck yeah! You pressed submit!"
Else Print "Cancelled"
End If

Function TaskDlgCallback%& (hwnd As _Offset, msg As _Unsigned Long, wParam As _Unsigned _Offset, lParam As _Offset, lpRefData As _Offset)
    Static As Long progressPos
    Select Case msg
        Case TDN_BUTTON_CLICKED
            Select Case wParam
                Case TDCBF_OK_BUTTON
                    Print "Button value = Ok"
                Case TDCBF_YES_BUTTON
                    Print "Button value = Yes"
                Case TDCBF_NO_BUTTON
                    Print "Button value = No"
                Case TDCBF_CANCEL_BUTTON
                    Print "Button value = Cancel"
                Case TDCBF_RETRY_BUTTON
                    Print "Button value = Retry"
                    'Case TDCBF_CLOSE_BUTTON     'This one is not used
                    '    Print "Button value = Close"
            End Select
            Print wParam
        Case TDN_CREATED
            Print "Dialog has been created"
            If SendMessage(hwnd, TDM_ENABLE_BUTTON, TDCBF_YES_BUTTON, 0) = 0 Then
                Print "Submit button should be disabled"
            End If
            If SendMessage(hwnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, TDCBF_YES_BUTTON, 1) = 0 Then
                Print "Submit button has UAC shield"
            End If
            If SendMessage(hwnd, TDM_SET_PROGRESS_BAR_MARQUEE, 1, 0) = 0 Then
            End If
        Case TDN_DESTROYED
            Print "Dialog has been destroyed"
        Case TDN_DIALOG_CONSTRUCTED
            Print "Dialog has been constructed"
        Case TDN_EXPANDO_BUTTON_CLICKED
            If wParam Then
                Print "Dialog is expanded"
            Else Print "Dialog is collapsed"
            End If
        Case TDN_HELP
            Print "User pressed F1! They must want help!"
            Dim As TASKDIALOGCONFIG tdconfig
            Dim As String title: title = ANSIToUnicode("This is a new page" + Chr$(0))
            tdconfig.pszWindowTitle = _Offset(title)
            Dim As String header: header = ANSIToUnicode("This is the header on page 2" + Chr$(0))
            tdconfig.pszMainInstruction = _Offset(header)
            tdconfig.pszMainIcon = TD_INFORMATION_ICON
            tdconfig.pfCallback = TaskDialogCallback
            tdconfig.cbSize = Len(tdconfig)
            If SendMessage(hwnd, TDM_NAVIGATE_PAGE, 0, _Offset(tdconfig)) = 0 Then
                Print "Changing pages"
            End If
        Case TDN_HYPERLINK_CLICKED
            Dim As String hyperlink: hyperlink = wCharPtrToString(lParam)
            Print "Looks like the hyperlink was clicked! Here it is!: "; hyperlink
            Dim As String newContent: newContent = ANSIToUnicode("I've changed the text because I clicked the hyperlink!" + Chr$(0))
            If SendMessage(hwnd, TDM_UPDATE_ELEMENT_TEXT, TDE_CONTENT, _Offset(newContent)) = 0 Then
                Print "Updated content"
            End If
            'If SendMessage(hwnd, TDM_UPDATE_ICON, TDIE_ICON_MAIN, TD_SEC_SUCCESS_ICON) = 0 Then
            '    Print "Icon changed"
            'End If
            Shell _Hide _DontWait "start " + hyperlink
        Case TDN_NAVIGATED
            Print "Navigation of some sort has occurred"
        Case TDN_RADIO_BUTTON_CLICKED
            Print "Radio button"; wParam; " was clicked"
        Case TDN_TIMER
            'Print "It's been"; wParam; " milliseconds since creation"
            progressPos = progressPos + 5
            If progressPos <= 100 Then
                If SendMessage(hwnd, TDM_SET_PROGRESS_BAR_POS, progressPos, 0) = 0 Then
                End If
                If progressPos = 100 Then
                    If SendMessage(hwnd, TDM_ENABLE_BUTTON, TDCBF_YES_BUTTON, 1) = 0 Then
                        Print "Enabled"
                        If SendMessage(hwnd, TDM_SET_MARQUEE_PROGRESS_BAR, 0, 0) = 0 Then
                        End If
                        If SendMessage(hwnd, TDM_SET_PROGRESS_BAR_MARQUEE, 0, 0) = 0 Then
                        End If
                        If SendMessage(hwnd, TDM_SET_PROGRESS_BAR_POS, progressPos, 0) = 0 Then
                        End If
                    End If
                End If
            End If
        Case TDN_VERIFICATION_CLICKED
            If wParam Then
                Print "The checkbox is checked!"
            Else Print "The checkbox is unchecked"
            End If
    End Select
End Function

Function wCharPtrToString$ (wchar As _Offset)
    Declare CustomType Library
        Function wcslen%& (ByVal str As _Offset)
    End Declare
    Dim As _Offset wlen: wlen = wcslen(wchar) * 2
    Dim As _MEM pChar: pChar = _Mem(wchar, wlen)
    Dim As String char: char = Space$(wlen)
    _MemGet pChar, pChar.OFFSET, char
    _MemFree pChar
    wCharPtrToString = UnicodeToANSI(char)
End Function

'$INCLUDE:'unicodetoansi.bas'
