IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Classes Fenêtres et FrameWork > Boite de Dialogue > CFileDialog
        Comment utiliser une CFileDialog ?
        Comment récupérer le répertoire courant dans une CFileDialog ?
        Comment récupérer la sélection de type de fichier en cours dans une CFileDialog ?
        Quels sont les événements interceptables sur une CFileDialog ?



Comment utiliser une CFileDialog ?
Mise à jour le 23/03/2008[haut]
auteur : Farscape
La classe CFileDialog fait partie des boîtes de dialogue standards dérivées de la classe CCommonDialog.
Listes des boites de dialogues standard de ComDLG32:

  • CColorDialog: Permet de sélectionner et créer une couleur
  • CFileDialog : permet d'enregistrer ou d'ouvrir un fichier.
  • CFindReplaceDialog : permet de remplacer une chaîne de caractères par une autre.
  • CFontDialog : permet de choisir une police parmi celles du système.
  • CPrintDialog : permet de sélectionner de configurer l'imprimante et d'imprimer un document.

CFileDialog::CFileDialog
CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, 
                   LPCTSTR lpszFileName = NULL, 
                  DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, 
                  LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );
Exemples d'utilisation de CFileDialog :

Ouverture d'un fichier :

CString OpenFilter;
OpenFilter = "Text File (*.txt)|*.txt||";

CFileDialog FileOpenDialog(
      TRUE,
      NULL,
      NULL,
      OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,
      OpenFilter,                       // filter
      AfxGetMainWnd());               // the parent window 
if(FileOpenDialog.DoModal()==IDOK)
    {
        CFile File;
        VERIFY(File.Open(FileOpenDialog.GetPathName(),CFile::modeRead));
    }
Sélections multiples de fichiers :

CString OpenFilter;
OpenFilter = "Text File (*.txt)|*.txt|";
OpenFilter += "All Files (*.*)|*.*||";

CFileDialog FileOpenDialog(
TRUE,
NULL,
NULL,
OFN_ALLOWMULTISELECT|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,
OpenFilter,        // filter
AfxGetMainWnd());// the parent window
	CString fileName;
	const int c_cMaxFiles = 100; // 100 fichiers maximum
	const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;
	FileOpenDialog.GetOFN().lpstrFile = fileName.GetBuffer(c_cbBuffSize);
	FileOpenDialog.GetOFN().nMaxFile = c_cbBuffSize; // attention : malgré le 
									// nom de l'attribut, il s'agit bien de la 
									// taille du buffer et non du nombre
									// max de fichier !

     if(FileOpenDialog.DoModal()==IDOK)
     {
        POSITION pos=FileOpenDialog.GetStartPosition();
        while(pos)
        {
            AfxMessageBox(FileOpenDialog.GetNextPathName(pos));
        }
    }
    fileName.ReleaseBuffer();
Sauvegarde d'un fichier :

CFileDialog FileOpenDialog( FALSE, "dat", NULL, OFN_HIDEREADONLY, "Fichiers (*.dat)|*.dat||" );
Spécification du répertoire d'origine :

CFileDialog FileOpenDialog( FALSE, "dat", NULL, OFN_HIDEREADONLY, "Fichiers (*.dat)|*.dat||" );
FileOpenDialog.m_ofn.lpstrInitialDir="c:\\myprojects";

Comment récupérer le répertoire courant dans une CFileDialog ?
auteur : Farscape
En surchargeant la méthode virtuelle OnFolderChange qui est appelée à chaque changement de répertoire (message WM_NOTIFY).
La récupération du nom se fait par la fonction CommDlg_OpenSave_GetFolderPath
Pour plus de détails se reporter à la note d'information MSDN : CDM_GETFOLDERPATH Message

/////////////////////////////////////////////////////////////////////////////
// CMyFileDialog

class CMyFileDialog : public CFileDialog
{
DECLARE_DYNAMIC(CMyFileDialog)

public:
CMyFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
       LPCTSTR lpszDefExt = NULL,
       LPCTSTR lpszFileName = NULL,
       DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
       LPCTSTR lpszFilter = NULL,
      CWnd* pParentWnd = NULL);

virtual void OnFolderChange( );

public:
CString m_szDirName;

protected:
//{{AFX_MSG(CMyFileDialog)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};


IMPLEMENT_DYNAMIC(CMyFileDialog, CFileDialog)

CMyFileDialog::CMyFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
    DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
    CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
}


BEGIN_MESSAGE_MAP(CMyFileDialog, CFileDialog)
//{{AFX_MSG_MAP(CMyFileDialog)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/*virtual*/ void CMyFileDialog::OnFolderChange()
{
   // 
   char buf[256];
   CommDlg_OpenSave_GetFolderPath( GetParent()->m_hWnd, buf, 256 );
   m_szDirName = buf;
}
Après DoModal la variable m_szDirNamecontient le chemin complet du répertoire en cours de sélection.


Comment récupérer la sélection de type de fichier en cours dans une CFileDialog ?
auteur : Farscape
Il faut faire une classe dérivée de CFileDialog (avec classwizard) et redéfinir la fonction virtuelle :
virtual void OnTypeChange()
Elle est appelée à chaque changement de sélection par l'intermédiaire d'un message WM_NOTIFY.

L'étape suivante consiste à trouver la ComboBox de sélection.
Dans mon exemple j'ai fais un premier essai avec un message avec la macro TRACE pour repérer son identifiant , c'est le code entre commentaire.
Après j'accède directement à la valeur de la zone par un GetWindowText.

/*virtual */void CMyFileDialog::OnTypeChange()
{
    CString str;
    CWnd *pWnd=this; 
    /*char sz[256]; 
    bool bFirst=true;
    while(pWnd=pWnd->GetWindow(bFirst?GW_HWNDFIRST:GW_HWNDNEXT))
    {
        bFirst=false;
        if(GetClassName(pWnd->GetSafeHwnd(),sz,sizeof(sz)))
        {
            if(CString(sz)=="ComboBox")
            {
                pWnd->GetWindowText(str);
                TRACE("\ntype:%s- %u",(const char *)str,pWnd->GetDlgCtrlID());
            }
        }  
    }*/   
    pWnd=GetParent();
    pWnd->GetDlgItem(1136)->GetWindowText(str);
    TRACE("\n%s",(const char *)str);
}

Quels sont les événements interceptables sur une CFileDialog ?
auteur : Farscape
Il suffit d'aller regarder la fonction OnNotify dans le source de la classe CFileDialog pour avoir un aperçu rapide !

BOOL CFileDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    ASSERT(pResult != NULL);
    
    // allow message map to override
    if (CCommonDialog::OnNotify(wParam, lParam, pResult))
        return TRUE;
    
    OFNOTIFY* pNotify = (OFNOTIFY*)lParam;
    switch(pNotify->hdr.code)
    {
    case CDN_INITDONE:OnInitDone();
                      return TRUE;
    case CDN_SELCHANGE:OnFileNameChange();
                      return TRUE;
    case CDN_FOLDERCHANGE:OnFolderChange();
                      return TRUE;
    case CDN_SHAREVIOLATION:
                      *pResult = OnShareViolation(pNotify->pszFile);
                      return TRUE;
    case CDN_HELP:if (!SendMessage(WM_COMMAND, ID_HELP))
                 SendMessage(WM_COMMANDHELP, 0, 0);
                      return TRUE;
    case CDN_FILEOK:*pResult = OnFileNameOK();
                      return TRUE;
    case CDN_TYPECHANGE:OnTypeChange();
                      return TRUE;
    }    
    return FALSE
}
Les fonctions qui suivent sont disponibles si le type OFN_EXPLORER est utilisé à la création de la boîte de dialogue.

  • virtual void OnInitDone( ) :
    Appelée quand la boîte de dialogue est entièrement initialisée
  • virtual void OnFileNameChange( ) :
    Appelée quand l'utilisateur sélectionne un nouveau fichier ou répertoire.
  • virtual void OnFolderChange( ) :
    Appelée quand un nouveau répertoire est ouvert .
  • virtual UINT OnShareViolation( LPCTSTR lpszPathName ) :
    Permet de maîtriser le mécanisme de violation de partage sur un fichier .
    Si on ne veut pas de message il faut mettre le type OFN_SHAREAWARE dans m_ofn.Flags.
  • virtual BOOL OnFileNameOK :
    Permet de gérer la validité du nom proposé dans la sélection lors de l'appui sur le bouton OK.
  • virtual void OnTypeChange():
    Appelée quand l'utilisateur sélectionne un nouveau type de fichier dans la ComboBox de sélection.
Voici les fonctions permettant de récupérer directement des valeurs :
CommDlg_OpenSave_GetSpec :

char buf[256]; 
CommDlg_OpenSave_GetSpec( GetParent()->m_hWnd, buf, 256 );
CommDlg_OpenSave_GetFilePath : récupération du chemin du fichier en cours de sélection.

char buf[256]; 
CommDlg_OpenSave_GetFilePath ( GetParent()->m_hWnd, buf, 256 );
CommDlg_OpenSave_GetFolderPath : récupération du répertoire en cours de sélection :

char buf[256]; 
CommDlg_OpenSave_GetFolderPath( GetParent()->m_hWnd, buf, 256 );
CommDlg_OpenSave_GetFolderIDList(hDlg, pidl, cbmax) :permet de récupérer une structure ITEMIDLIST sur le répertoire courant .
Voir MSDN pour de plus amples renseignements.

Pour finir voici une technique pour récupérer un pointeur sur un des éléments de la boite de dialogue.
Le code ci-dessus itère sur les fenêtres filles de la boîte de dialogue pour trouver un contrôle de type ComboBox.
A adapter selon ses besoins.

/*virtual */ void CMyFileDialog::OnInitDone( ) 
{
 CWnd *pWnd=this; 
 char sz[256]; 
  bool bFirst=true; 
   while(pWnd=pWnd->GetWindow(bFirst?GW_HWNDFIRST:GW_HWNDNEXT)) 
   { 
      bFirst=false; 
      if(GetClassName(pWnd->GetSafeHwnd(),sz,sizeof(sz))) 
      { 
         if(CString(sz)=="ComboBox") 
         { 
            pWnd->GetWindowText(str); 
            TRACE("\ntype:%s- %u",(const char *)str,pWnd->GetDlgCtrlID()); 
         } 
      }        
   }
}
// Utilisation finale avec un numéro de contrôle trouvé, ici le sélecteur de type de fichiers.
CWnd *pWnd=GetParent(); 
pWnd->GetDlgItem(1136)->GetWindowText(str); 


Consultez les autres F.A.Q.


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.