Attribute VB_Name = "hlp_MsgBoxCB"
Option Explicit
Option Base 0

'Modal = waittillfinished before returning
  '  DialogBox[Indirect]

'buttonid -> ffff; 0 =closed or escaped!
'checked: 0/1

Private Const MsgBoxCB_Disabled = -1&
Private Declare Function CallWindowProcA Lib "user32" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private xCheckBoxCtlID As Long
Private xEscBehaviour As Long
Private xButtonCtlID As Long
Private xIconCtlID As Long
Private xIconResID As Long
Private xRadio1 As Long
Private xRadio2 As Long
Private xCallBackProc As Long

Private Declare Function GetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function DialogBoxIndirectParamA Lib "user32" (ByVal hInstance As Long, hDialogTemplate As Any, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal xParam As Long) As Long
'Private Declare Function CreateDialogIndirectParamA Lib "user32" (ByVal hInstance As Long, lpTemplate As Any, ByVal hWndParent As Long, ByVal lpDialogFunc As Long, ByVal xParam As Long) As Long
Public Declare Function GetDlgItem Lib "user32" (ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
Private Declare Function EndDialog Lib "user32" (ByVal hDlg As Long, ByVal nResult As Long) As Long
Public Declare Function CheckDlgButton Lib "user32" (ByVal hDlg As Long, ByVal nIDButton As Long, ByVal wCheck As Long) As Long
Public Declare Function CheckRadioButton Lib "user32" Alias "CheckRadioButtonA" (ByVal hDlg As Long, ByVal nIDFirstButton As Long, ByVal nIDLastButton As Long, ByVal nIDCheckButton As Long) As Long
Public Declare Function IsDlgButtonChecked Lib "user32" (ByVal hDlg As Long, ByVal nIDButton As Long) As Long
Public Declare Function SetDlgItemTextA Lib "user32" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal lpString As String) As Long
Public Declare Function GetDlgItemTextA Lib "user32" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Long

Public Function MsgBoxCB_InternalProc(ByVal HWndDialog As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Select Case Msg
    Case &H10&
      If Not xEscBehaviour = MsgBoxCB_Disabled Then
        Call EndDialog(HWndDialog, xEscBehaviour)
        End If
    Case &H111& 'wm_command
      If lParam = 0& Then
        If wParam = 2& And Not xEscBehaviour = MsgBoxCB_Disabled Then
          Call EndDialog(HWndDialog, xEscBehaviour)
          End If
        Else
        If (GetWindowLongA(lParam, -16&) And &HE&) = 0& Then
          If Not (wParam = 0& And xEscBehaviour = MsgBoxCB_Disabled) Then
            If Not xCheckBoxCtlID = 0& Then
              If xRadio1 = 0& Then
                xCheckBoxCtlID = IsDlgButtonChecked(HWndDialog, xCheckBoxCtlID)
                Else
                xCheckBoxCtlID = 0&
                For lParam = xRadio1 To xRadio2
                  If Not IsDlgButtonChecked(HWndDialog, lParam) = 0& Then
                    xCheckBoxCtlID = xRadio1
                    Exit For
                    End If
                  Next
                End If
              End If
            If xCallBackProc = 0& Then
              Call EndDialog(HWndDialog, wParam)
              Else
              'Debug.Print CallWindowProcA(xCallBackProc, HWndDialog, Msg, wParam, lParam)
              If CallWindowProcA(xCallBackProc, HWndDialog, Msg, wParam, lParam) = 1& Then
                'Debug.Print "Can!"
                Call EndDialog(HWndDialog, wParam)
                End If
              End If
            End If
          Else
          'checkbox or option
          If (GetWindowLongA(lParam, -16&) And &HC&) = 0& Then
            If IsDlgButtonChecked(HWndDialog, wParam) = 0& Then
              lParam = 1&
              Else
              lParam = 0&
              End If
            Call CheckDlgButton(HWndDialog, xCheckBoxCtlID, lParam)
            ElseIf wParam >= xRadio1 And wParam <= xRadio2 Then
            Call CheckRadioButton(HWndDialog, xRadio1, xRadio2, wParam)
            End If
          End If
        End If
    Case &H110&
      'init dialog
      'xCheckBoxCtlID = CheckBoxControlID
      If xRadio1 = 0& Then
        If xCheckBoxCtlID < 0& Then
          xCheckBoxCtlID = -xCheckBoxCtlID
          MsgBoxCB_InternalProc = 1&
          ElseIf Not xCheckBoxCtlID = 0& Then
          MsgBoxCB_InternalProc = 0&
          End If
        Call CheckDlgButton(HWndDialog, xCheckBoxCtlID, MsgBoxCB_InternalProc)
        'xButtonCtlID = DefaultButtonID
        ElseIf wParam >= xRadio1 And wParam <= xRadio2 Then
        Call CheckRadioButton(HWndDialog, xRadio1, xRadio2, wParam)
        End If
      If Not xCallBackProc = 0& Then
        Call CallWindowProcA(xCallBackProc, HWndDialog, Msg, wParam, lParam)
        End If
      MsgBoxCB_InternalProc = 1&
    'Case wm_key
    '  wParam = GetNextDlgTabItem(HWndDialog, 0&, 0&)
'    Case &H100& To &H10F&
'      Debug.Print "DLG:", Hex(Msg), wParam, lParam
    End Select
'  Debug.Print "DLG:", Hex(Msg), wParam, lParam
  End Function

' result, or 0/1
' CheckControlID: checkboxid, or radio id (must specify RadioButtonFirst / Last!!!)
'
Public Function MsgBoxCB(ByVal HwndOwner As Long, ByVal ResDialogID As Long, Optional ByRef CheckControlID As Long = 0&, Optional DefaultButtonID As Long = 0&, Optional ByVal CanEscapeControlID As Long = MsgBoxCB_Disabled, Optional ByVal IconControlID As Long, Optional ByVal IconResID As Long, Optional ByVal RadioButtonFirstID As Long, Optional ByVal RadioButtonLastID As Long, Optional ByVal CallBackProc As Long) As Long
  Dim xChar1 As String
  xChar1 = LoadResEx_Data("#" + CStr(ResDialogID), "#5", True)
  If Not Len(xChar1) = 0& Then
    xCallBackProc = CallBackProc
    xEscBehaviour = CanEscapeControlID
    xCheckBoxCtlID = CheckControlID
    xButtonCtlID = DefaultButtonID
    xIconCtlID = IconControlID
    xIconResID = IconResID
    xRadio1 = RadioButtonFirstID
    xRadio2 = RadioButtonLastID
    If xRadio2 = 0& And Not xRadio1 = 0& Then xRadio2 = xRadio1
    MsgBoxCB = DialogBoxIndirectParamA(App.hInstance, ByVal xChar1, HwndOwner, AddressOf MsgBoxCB_InternalProc, 0&) ', ResDialogID)
    CheckControlID = xCheckBoxCtlID
    'If Not MsgBoxCB = 0& Then
    '  Call SetWindowPos(MsgBoxCB, 0&, 0&, 0&, 0&, 0&, &H243&)
    '  End If
    End If
  End Function

'Public Function MyCallBack(ByVal HWndDialog As Long, ByVal Msg As Long, ByVal ControlHWnd As Long, ByVal ControlID As Long) As Long
'  Debug.Print Msg, ControlHWnd, ControlID
'  MyCallBack = 1&
'  End Function
