IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Classe d'application (CWinApp)
        Comment récupérer le pointeur sur l'application?
        Comment récupérer le nom de l'application ?
        Comment trouver le nom de l'exécutable (uniquement) ?
        Comment retrouver le chemin de l'exécutable (uniquement) ?
        Comment changer le nom d'une application MFC ?
        Comment démarrer l'application en mode maximisé ?
        Comment récupérer le pointeur sur la fenêtre principale de l'application ?
        Comment parcourir dans un contexte MDI toutes les fenêtres de l'application ?
        Comment empêcher de lancer plusieurs instances d'un programme ?
        Comment enregistrer les extensions de documents dans l'explorateur Windows ?
        Comment récupérer la ligne d'arguments passée à l'application ?
        Comment mettre en place une variable globale dans un projet ?
        Comment récupérer une CString de la liste des fichiers récents ( Most Recently Used ) ?
2.1. Les Fichiers .ini (8)
                Comment faire pour écrire et lire dans un fichier .ini ?
                Comment stocker une zone binaire dans un .ini ?
                Comment lire/écrire un entier dans un .ini ?
                Comment faire pour changer le nom du .ini dans une application MFC ?
                Comment utiliser les autres fonctions dédiées aux fichiers .ini dans une application MFC ?
                Comment compter le nombre de sections d'un fichier ini ?
                Comme travailler avec un fichier INI avec eMbedded visual C++?
                Comment supprimer une clef ou une section dans un fichier .ini ?



Comment récupérer le pointeur sur l'application?
auteur : Farscape
en appelant la fonction globale:
 
AfxGetApp() ; 
 
CWinApp* AfxGetApp( ); 
On pourra aussi disposer de la ligne de commande de l'application :

AfxGetApp()->m_lpCmdLine

Comment récupérer le nom de l'application ?
auteur : Farscape

AfxGetAppName() ;
// ou 
AfxGetApp()->m_pszAppName

Comment trouver le nom de l'exécutable (uniquement) ?
Créé le 04/04/2005[haut]
auteur : nico-pyright(c)
// trouver le nom (uniquement) de l'executable
void GetNom(char *nom, DWORD taille)
{
char *c;
c = nom + GetModuleFileName(NULL,nom,taille);
while(*c!='\\') c--;
strcpy(nom,++c);
}
ou
// trouver le nom (uniquement) de l'executable (CString)
CString CGetNom(char *nom, DWORD taille)
{
GetModuleFileName(NULL,nom,taille);
CString Cnom(nom);
return Cnom.Mid(Cnom.ReverseFind('\\')+1);
}
Appel :

char nom[MAX_PATH];
GetNom(nom,MAX_PATH);

// ou
char nom[MAX_PATH];
CString Cnom = CGetNom(nom, MAX_PATH);

Comment retrouver le chemin de l'exécutable (uniquement) ?
Créé le 04/04/2005[haut]
auteur : nico-pyright(c)

// trouver le chemin (uniquement) de l'application
void GetChemin(char *chemin, DWORD taille)
{
char *c;
c = chemin + GetModuleFileName(NULL,chemin,taille);
while(*c!='\\')
c--;
*c=0;
}
ou

// trouver le chemin (uniquement) de l'application (CString)
CString CGetChemin(char *chemin, DWORD taille)
{
GetModuleFileName(NULL,chemin,taille);
CString Cchemin(chemin);
return Cchemin.Mid(0,Cchemin.ReverseFind('\\'));
}
Appel :
char chemin[MAX_PATH];
GetChemin(chemin, MAX_PATH);

// ou
CString Cchemin = CGetChemin(chemin, MAX_PATH);
AfxMessageBox(Cchemin);

Comment changer le nom d'une application MFC ?
auteur : Farscape
En utilisant la fonction AfxSetWindowText.
Cette fonction n'est pas documentée !
Il faut l'appeler dans InitInstance après l'initialisation de la MainFrame

// a rajouter pour la définition 
#include <afxpriv.h> 

pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
AfxSetWindowText(m_pMainWnd->m_hWnd,"TestSDI- Farscape");    

Comment démarrer l'application en mode maximisé ?
auteur : Farscape
Dans la fonction InitInstance de la classe d'application modifier comme suit :

m_nCmdShow = SW_SHOWMAXIMIZED ;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();

Comment récupérer le pointeur sur la fenêtre principale de l'application ?
auteur : Farscape

CWnd* AfxGetMainWnd( );

CMyMainFrame *p=(CMyMainFrame *)AfxGetMainWnd() ;

Comment parcourir dans un contexte MDI toutes les fenêtres de l'application ?
auteur : Farscape
Le point de départ c'est la classe d'application qui donne accès aux documents Template.

CWinApp* pApp = AfxGetApp();        
// parcourir tous les templates
CDocTemplate* pTemplate;
POSITION pos = pApp->GetFirstDocTemplatePosition();
while (pos != NULL)
{
    pTemplate = pApp->GetNextDocTemplate(pos);
    ASSERT(pTemplate);

    // tous les documents du template.
    POSITION pos2 = pTemplate->GetFirstDocPosition();
    while (pos2)
    {
        CDocument* pDoc = pTemplate->GetNextDoc(pos2);
        ASSERT(pDoc);

        // toutes les vues du document
        POSITION pos3 = pDoc->GetFirstViewPosition();
        while (pos3 != NULL)
        {
            CView* pView = pDoc->GetNextView(pos3);
            ASSERT(pView);
            if (::IsWindow(pView->GetSafeHwnd()))
            {
                if(pView->IsKindOf(RUNTIME_CLASS(CFormView)))
                {
                // une forme view
                }
                else
                if(pView->IsKindOf(RUNTIME_CLASS(CScrollView)))
                {
                // une  Scrollview
                }
                else
                if(pView->IsKindOf(RUNTIME_CLASS(CView)))
                {
                    // une  view
                }
            }
        }
    }
}

Comment empêcher de lancer plusieurs instances d'un programme ?
Mise à jour le 10/09/2005[haut]
auteur : Farscape
Plusieurs solutions peuvent être employées.
La plus simple à mon avis consiste à utiliser la possibilité de partager des variables pour tous les processus du programme.

// déclaration d'une section TestApp

#pragma data_seg("TestApp") 

// la variable commune a tous les process
LONG nCtApp = -1; 
#pragma data_seg()

// directive pour le link.

#pragma comment(linker, "/section:TestApp,rws") 

// Test incrémentation de la variable. 

bool bFirstInstance =  (InterlockedIncrement(&nCtApp) == 0);
if(!bFirstInstance)
{
       // erreur le prog est déjà lancé.
}
Voir la note d'information MSDN sur le sujet : HOWTO: Specify Shared and Nonshared Data in a DLL Q100634
Autre solution possible, utiliser un objet Mutex.
exemple:

// .h
//
class CSdisamplesApp : public CWinApp
{
public:
CSdisamplesApp();
    ~CSdisamplesApp();
    CMutex     m_Mutex;
    bool       m_bLock;
    //................

// .cpp
CSdisamplesApp::CSdisamplesApp():m_bLock(false),m_Mutex(FALSE,"SDISAMPLE")
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
CSdisamplesApp::~CSdisamplesApp()
{
// Destruct
    if(m_bLock) m_Mutex.Unlock();    
}    
BOOL CSdisamplesApp::InitInstance()
{    
    if(!(m_bLock=m_Mutex.Lock(0)))
    {
        AfxMessageBox("Application active");
        return(0);
    }
//................

Comment enregistrer les extensions de documents dans l'explorateur Windows ?
auteur : Farscape
Dans un projet MFC pour chaque document template on peut associer une extension de fichier .
Comment faire pour que lorsque l'on double-clique sur un document géré par l'application celle ?ci s'exécute ?
Il faut enregistrer les extensions dans la base de registre .
Pour un programme MFC il y a une fonction qui fait ce travail :

void RegisterShellFileTypes( BOOL bCompat = FALSE );
La valeur bCompat a TRUE permet l'insertion des entrées impression et impression sur dans la base de registre ainsi que le sélectionner glisser lâcher du document sur une imprimante.

Cette fonction est à insérer derrière le dernier AddocTemplate dans la fonction InitInstance de la classe d'application.
La fonction EnableShellOpen doit être appelée.

BOOL CMyApp::InitInstance() 
{ 
   // ... 

   CMultiDocTemplate* pDocTemplate; 
   pDocTemplate = new CMultiDocTemplate( 
      IDR_MYTYPE, 
      RUNTIME_CLASS(CMyDoc), 
      RUNTIME_CLASS(CMDIChildWnd),        // standard MDI child frame 
      RUNTIME_CLASS(CMyView)); 
   AddDocTemplate(pDocTemplate); 

   // Create main MDI Frame window. 
   CMainFrame* pMainFrame = new CMainFrame; 
   if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) 
      return FALSE; 
   // Save the pointer to the main frame window.  This is the 
   // only way the framework will have knowledge of what the 
   // main frame window is. 
   m_pMainWnd = pMainFrame; 

   // enable file manager drag/drop and DDE Execute open 
   EnableShellOpen(); 
   RegisterShellFileTypes(); 
   // ... 

   // Show the   main window using the nCmdShow parameter 
   // passed to the application when it was first launched. 
   pMainFrame->ShowWindow(m_nCmdShow); 
   pMainFrame->UpdateWindow(); 
  
   // ... 
}

Comment récupérer la ligne d'arguments passée à l'application ?
Créé le 27/11/2005[haut]
auteur : Farscape
La classe CWinApp (classe d'application) permet d'accéder à la ligne de commande par l'intermédiaire de sa donnée membre m_lpCmdLine

On pourra l'utiliser directement dans la fonction InitInstance, ou y accéder de partout dans l'application grâce à la fonction globale AfxGetApp()

 AfxGetApp()->m_lpCmdLine.
Les arguments sont séparés par un blanc, pour disposer de la liste comme dans un programme classique en C avec la fonction main, on pourra procéder de la manière suivante :

BOOL CSampleSDIApp::InitInstance()
{
    AfxEnableControlContainer();

    char szName[MAX_PATH];    
    GetModuleFileName(NULL,szName,MAX_PATH);

    CArray<CString ,const char *> argv; // attention il faut mettre #include <afxtempl.h> dans stdafx.h

    char *szArg=strtok(m_lpCmdLine," ");

    argv.Add(szName); // argv[0]=path de l'application.
    if(szArg) 
    {
        do
       {
          argv.Add(szArg);
       }
       while(szArg=strtok(NULL," "));
   }

    int argc=argv.GetSize();
    for(int i=0;i<argc;i++)
    {
        TRACE("\nArgv[%d]=%s",i,argv[i]);
    }
//..........................

Comment mettre en place une variable globale dans un projet ?
Créé le 22/01/2007[haut]
auteur : Farscape
L'utilisation d'une variable globale objet a travers un projet est parfois nécessaire.
Je vous propose deux méthodes pour y parvenir:
Utiliser l'instance d'application pour stocker notre variable globale :
En effet une application MFC génère une seule instance de la classe d'application qui a la particularité d'être disponible à tout instant en utilisant la fonction globale AfxGetApp().
Il me suffira donc de déclarer l'objet ou la fonction à partager dans le projet dans la classe d'application et d'y accéder comme suit :

CMyApp *pApp=static_cast<CMyApp *>(AfxGetApp());
pApp->m_Global.MyFunction();     //exemple de fonction globale 
CListCtrm &rList=pApp->m_Global.GetLisCtrl(); // variable globale.

Autre solution utiliser le pattern Singleton : Définition
Le pattern Singleton garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à cette instance.

L'Exemple qui suit est adapté de ma lecture du livre : Design Patterns tête la première (en java mais très accessible à un lecteur C++).


namespace Singleton {

class MyClass
{
    private: static MyClass*  m_pUniqueInstance;
    private: static CMutex      m_LockInstance; // warning -> :#include <afxmt.h>

    private: MyClass(const MyClass&); // Disable copy constructor
    private: void operator=(const MyClass&); // Disable assignment operator

    private: MyClass()
    {
        // Initialisations
    }
    private: ~MyClass()
    { 
        m_pUniqueInstance = 0;
    }
    public: static MyClass &GetInstance()
    {
        if (m_pUniqueInstance == 0)
        {            
            m_LockInstance.Lock();
            if (m_pUniqueInstance == 0)
                m_pUniqueInstance = new MyClass();
            m_LockInstance.Unlock();
        }        
        return *m_pUniqueInstance;
    }
    public: static void FreeInstance()
    {
        m_LockInstance.Lock();
        delete m_pUniqueInstance;
        m_LockInstance.Unlock();
    }
    // users functions.    
    void UserFunction()
   {
        ASSERT(m_pUniqueInstance);
   }

};

}
// namespace Singleton
// init static data
CMutex     Singleton::MyClass::m_LockInstance;
Singleton::MyClass*  Singleton::MyClass::m_pUniqueInstance=NULL;

// utilisation.
Singleton::MyClass &theClass=Singleton::MyClass::GetInstance();
theClass.UserFunction();
// ou
Singleton::MyClass::GetInstance().UserFunction();
// libération
Singleton::MyClass::FreeInstance();
Il existe de multiples exemples où le singleton est utile : objet de journalisation, de préférence de l'application etc ..
L'exemple que j'ai implémenté utilise un Mutex pour contrôler la création de l'instance, ce qui est préférable dans un contexte d'utilisation multithreads.
Ce même mutex pourra être utilisé pour gérer des accès à des variables ou des fonctions de la classe.
On placera la définition de la classe singleton dans l' include de la classe d'application pour que sa définition soit disponible dans toute l'application.
La déclaration des variables static pourra être faite dans le source de la classe d'application.


Comment récupérer une CString de la liste des fichiers récents ( Most Recently Used ) ?
Créé le 22/01/2007[haut]
auteur : Farscape
Une application MFC met en place une MRU ( Most Recently Used ), mais ne fournit pas d'accès directe à celle-ci pour y accéder .
En cherchant dans le code des MFC et plus exactement dans la fonction LoadStdProfileSettings on s'aperçoit que la liste est gérée par la donnée membre m_pRecentFileList de la classe CRecentFileList

void CWinApp::LoadStdProfileSettings(UINT nMaxMRU)
{
    ASSERT_VALID(this);
    ASSERT(m_pRecentFileList == NULL);

    if (nMaxMRU != 0)
    {
        // create file MRU since nMaxMRU not zero
        m_pRecentFileList = new CRecentFileList(0, _afxFileSection, _afxFileEntry,
            nMaxMRU);
        m_pRecentFileList->ReadList();
    }
    // 0 by default means not set
    m_nNumPreviewPages = GetProfileInt(_afxPreviewSection, _afxPreviewEntry, 0);
}

Pour accéder à cette liste déclarée protect dans la classe CWinApp on rajoutera un accesseur dans notre classe d'application :

class CMyApp : public CWinApp
{
public:
    CMyApp ();
    inline CRecentFileList *GetRecentFileList(){return m_pRecentFileList;}
//...
};

On rajoutera aussi le fichier :

#include <afxadv.h>

Dans stdafx.h

Exemple Utilisation :

void CTestToolBarView::OnInitialUpdate()
{
//...
  CMyApp *TheApp=static_cast<CMyApp *>(AfxGetApp());
    
    CString str;
    for( int i=0;TheApp->GetRecentFileList()->GetSize( );i++)
        str=(*TheApp->GetRecentFileList())[i];
}





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.