Attribute VB_Name = "mComCTL"
Option Explicit

'Declaración de la estructura OPENFILENAME
Private Type OPENFILENAME
    nStructSize As Long
    hWndOwner As Long
    hInstance As Long
    sFilter As String
    sCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    sFile As String
    nMaxFile As Long
    sFileTitle As String
    nMaxTitle As Long
    sInitialDir As String
    sDialogTitle As String
    Flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    sDefFileExt As String
    nCustData As Long
    fnHook As Long
    sTemplateName As String
    pvReserved As Long
    dwReserved As Long
    flagsEx As Long
End Type

Private Const OSv_LENGTH As Long = 76 'Anterior 2000

'Declaración mensajes y notificaciones
'Private Const WM_COMMAND = &H111
'Private Const WM_NOTIFY As Long = &H4E&
'Private Const WM_INITDIALOG As Long = &H110
'Private Const CDN_FIRST As Long = -601
'Private Const CDN_INITDONE As Long = (CDN_FIRST - &H0&)
Private Const MAX_PATH As Long = 260

'Constantes para openfilename
Private Const OFN_ENABLEHOOK As Long = &H20
Private Const OFN_EXPLORER As Long = &H80000
Private Const OFN_ENABLESIZING As Long = &H800000
'Private Const OFN_EX_NOPLACESBAR As Long = &H1

'Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As Any) As Long
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
Private Declare Function GetSaveFileName Lib "comdlg32.dll" Alias "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Long
'Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpClassName As String, ByVal lpWindowName As String) As Long
'Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long


Private Const WM_COMMAND = &H111
Private Const WM_NOTIFY As Long = &H4E&
Private Const WM_INITDIALOG As Long = &H110
'Private Const CDN_FIRST As Long = -601
'Private Const CDN_INITDONE As Long = (CDN_FIRST - &H0&)
'Private Const MAX_PATH As Long = 260

Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Long) As Long

Private OFN As OPENFILENAME
Private m_Vista As Long
Private swPreparat As Boolean


Private Function OFNHookProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim hWndParent As Long
    Dim hwndLv As Long
    Static bLvSetupDone As Boolean
    
    Select Case uMsg
        Case WM_INITDIALOG
            bLvSetupDone = False
        Case WM_NOTIFY
            If bLvSetupDone = False Then
                'Hwnd del CommonDialog
                hWndParent = GetParent(hWnd)
                hwndLv = FindWindowEx(hWndParent, 0, "SHELLDLL_DefView", vbNullChar)
                If hwndLv > 0 Then
                    Call SendMessage(hwndLv, WM_COMMAND, ByVal m_Vista, ByVal 0&)
                    bLvSetupDone = True
                End If
            End If
        Case Else
    End Select
End Function

Private Function FARPROC(pfn As Long) As Long
    FARPROC = pfn
End Function

Public Function LKCommon(ByRef tipo As String) As String
    Dim Valor As Boolean
    
    If swPreparat Then
        If tipo = "A" Then
            Valor = GetOpenFileName(OFN)
        Else
            Valor = GetSaveFileName(OFN)
        End If
        If Valor Then
            LKCommon = Trim$(Replace(OFN.sFile, Chr$(0), vbNullString))
        End If
    End If
End Function

Public Sub PreparaOpenDialog(ByRef tipo As String, ByRef Form As Form, ByRef Titulo As String, ByRef Filtro As String, ByRef RutaIni As String, ByRef nomFich As String, ByVal Imagen As Boolean)
    Dim m_flags
    
    'Tipo="A" para Abrir, "G" para Grabar
    m_flags = OFN_EXPLORER Or OFN_ENABLEHOOK Or OFN_ENABLESIZING ' No aparece Menu a la Izquierda

    ' Valores m_Vista: Lista: 28715, Mosaico: 28718, Thumbnail: 28717, Iconos: 28713, Detalle: 28716
    If Imagen Then
        m_Vista = 28717
    Else
        m_Vista = 28716
    End If
    ' Llenamos la estructura OpenFileName
    With OFN
        .nStructSize = OSv_LENGTH
        .hWndOwner = Form.hWnd     'Hwnd del formulario que utiliza el commondialog
        .sFilter = Replace(Filtro, "|", Chr$(0)) + Chr$(0) 'reemplazamos el caracter | por un chr(0) para el Filtro
        .nFilterIndex = 0
        
        If tipo = "A" Then
            .sFile = vbNullChar & vbNullChar & Space$(MAX_PATH)
        Else
            .sFile = nomFich & vbNullChar & vbNullChar & Space$(MAX_PATH)
        End If
        
        .nMaxFile = Len(.sFile)
        '.sDefFileExt = "*.bmp" & vbNullChar & vbNullChar
        '.sFileTitle = vbNullChar & Space$(512) & vbNullChar & vbNullChar
        '.nMaxTitle = Len(OFN.sFileTitle)
        If Len(RutaIni) > 0 Then
            .sInitialDir = RutaIni & vbNullChar & vbNullChar 'Directorio inicial del CommonDialog
        End If
        .sDialogTitle = Titulo
        .Flags = m_flags 'flags del CommonDialog
        .fnHook = FARPROC(AddressOf OFNHookProc) 'Dirección del Hook
    End With
    swPreparat = True
End Sub



