IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Classes Fenêtres et FrameWork > Traitements sur la MDI
        Comment avoir plusieurs fenêtres de type View dans un projet MDI ?
        Comment avoir plusieurs fenêtres différentes sur un objet document ?
        Comment maximiser une fenêtre fille (Child)?
        Comment restaurer une fenêtre fille(Child) ?
        Comment récupérer la MDIChild active ?
        Comment savoir si une fenêtre fille est iconisée ?
        Comment activer une fenêtre fille (child)?
        Comment activer et faire passer en premier plan une fenêtre fille (Child)?
        Comment faire pour qu'un projet MDI soit toujours en avant plan ?
        Comment changer la taille d'une View dans un contexte MDI?
        Comment mémoriser la position des fenêtres dans une application MFC ?
        Comment s'affranchir du mécanisme par défaut pour les titres des fenêtres dans un contexte document/view ?
        Comment griser le bouton et le menu fermeture d'une fenêtre MDI ?
        Comment créer une fenêtre MDI que l'on ne peut bouger ?
        Comment accéder à la vue active dans un projet SDI ?



Comment avoir plusieurs fenêtres de type View dans un projet MDI ?
auteur : Farscape
La gestion de plusieurs fenêtres dans un projet MDI passe par la déclaration dans la fonction InitInstance (classe d'application CWinApp ) d'objets de la classe CMultiDocTemplate.

BOOL CTestMdiApp::InitInstance()
{
    AfxEnableControlContainer();
    #ifdef _AFXDLL
    Enable3dControls();// Call this when using MFC in a shared DLL
    #else
    Enable3dControlsStatic();// Call this when linking to MFC statically
    #endif

// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
    SetRegistryKey(_T("Local AppWizard-Generated Applications"));

    LoadStdProfileSettings();
    // Load standard INI file options (including MRU)
    // Register the application's document templates.  Document templates
    //  serve as the connection between documents, frame windows and views.
    // CMultiDocTemplate *m_pTplMdiView;
    m_pTplMdiView = new CMultiDocTemplate (
                            IDR_TESTMDTYPE,
                            RUNTIME_CLASS(CTestMdiDoc),
                            // custom MDI child frame
                            RUNTIME_CLASS(CChildFrame), 
                            RUNTIME_CLASS(CTestMdiView));
                            AddDocTemplate(m_pTplMdiView);

    // deuxième document 
    // stockage du CMultiDocTemplate dans la classe application pour appel ultérieur.
    // CMultiDocTemplate * m_pTplEditView; dans le header.
    m_pTplEditView= new CMultiDocTemplate (
                            IDR_TESTMDTYPE,
                            RUNTIME_CLASS(CTestMdiDoc),
                            // custom MDI child frame
                            RUNTIME_CLASS(CChildFrame), 
                            RUNTIME_CLASS(CEditView));
                            AddDocTemplate(m_pTplEditView);
    // create main MDI Frame window
    CMainFrame* pMainFrame= new CMainFrame;
    if(!pMainFrame->LoadFrame(IDR_MAINFRAME))
        return FALSE;
    m_pMainWnd = pMainFrame;

    // Parse command line for standard shell commands, DDE, file open
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    // Dispatch commands specified on the command line
    if(!ProcessShellCommand(cmdInfo)) return FALSE;

    // The main window has been initialized, so show and update it.
    pMainFrame->ShowWindow(m_nCmdShow);
    pMainFrame->UpdateWindow();

    return TRUE;
}
Ci-dessus on a une déclaration classique pour gérer deux fenêtres différentes au sein du même programme.
La création de la deuxième fenêtre pourra se faire comme suit :

((CTestMdiApp  *)AfxGetApp())->m_pTplEditView->OpenDocumentFile(NULL) ;

Comment avoir plusieurs fenêtres différentes sur un objet document ?
auteur : Farscape
D'abord pour fixer les idées, dans quel cas a-t-on besoin d'avoir des fenêtres différentes pour un même document ?
Chaque fois que l'on voudra avoir un lien entre plusieurs fenêtres pour des échanges de données ou des représentations de données d'une manière différente, le document donnant, par ses méthodes, un point d'accès pratique et facile aux différentes fenêtres.
Exemple :
Dans une « CFormView » je saisis des données pour l'affichage d'un graphe,dans une CView je les dessine sous forme de tableau récapitulatif , et dans une autre « CView » je les représente sous forme de diagrammes ,histogrammes etc..

L'association de plusieurs fenêtres sur un seul document s'effectue sur la déclaration du document template dans la fonction InitInstance de la classe d'application.

/*
à declarer dans la classe app en tant que données membres
CMultiDocTemplate* m_pTwoDocTemplate;
CMultiDocTemplate* m_pFirstTemplate;
*/
// La définition principale
m_pFirstTemplate= new CMultiDocTemplate(IDR_TESTMDTYPE,
                                        RUNTIME_CLASS(CTestMdiDoc),
                                         // custom MDI child frame
                                        RUNTIME_CLASS(CChildFrame),
                                        RUNTIME_CLASS(CTestMdiView));
                                        AddDocTemplate(m_pFirstTemplate);

// la fenêtre supplémentaire.
m_pTwoDocTemplate=new CMultiDocTemplate(IDR_TESTMDTYPE,
                                        RUNTIME_CLASS(CTestMdiDoc),
                                        // custom MDI child frame
                                        RUNTIME_CLASS(CChildFrame), 
                                        RUNTIME_CLASS(CMyEditView));
// pas de AddocTemplate.
Ici le premier document template comprend une « CView » et la fonction AddocTemplate est appelée
le deuxième juste une déclaration du template sans faire l'appel à AddDocTemplate .
Pour rajouter un objet de la class CMyEditView par exemple dans la fonction OnInitialUpdate de la classe CTestMdiView on procédera comme suit:

void CTestMdiView::OnInitialUpdate() 
{
    CView::OnInitialUpdate();
    // TODO: Add your specialized code here and/or call the base class
    CTestMdiApp *TheApp=(CTestMdiApp*)AfxGetApp();
    CFrameWnd * pFrame =TheApp->m_pTwoDocTemplate->CreateNewFrame(GetDocument(),GetParentFrame());
   TheApp->m_pFirstTemplate->InitialUpdateFrame(pFrame,GetDocument()); 
}
Le même appel pouvant être fait en réponse à une commande sur un menu sur la view en cours.( CTestMdiView).
Les étapes du traitement:
Récupération de la classe application pour accéder au pointeur sur document template (m_pFirstTemplate)
Création d'une « Mdi » à partir du deuxième document template (m_pTwoDocTemplate)
Rattacher la MDI avec sa fenêtre CMyEditView au premier document template avec la fonction InitialUpdateFrame .

On répétera le même processus pour la description et la création d'une fenêtre supplémentaire.
Au final on aura bien un objet document avec plusieurs Fenêtres.
C'est vérifiable par exemple en parcourant les fenêtres à partir de l'objet document :

void CMyEditView::OnInitialUpdate() 
{
    CEditView::OnInitialUpdate();

    // TODO: Add your specialized code here and/or call the base class
    POSITION pos=GetDocument()->GetFirstViewPosition();
   CView *pView;
   do
   {
          pView=GetDocument()->GetNextView(pos);
   }
   while(pView);
}
Cette méthode permet de gérer l'apparition de fenêtres rattachées au même document à la demande..
Notes:
On n'est pas pour autant obligé de stocker des données communes dans le document.
Le document n'a pas de partie graphique visible.


Comment maximiser une fenêtre fille (Child)?
auteur : Farscape
En passant par les fonctions de la CMDIChildWnd .
A partir de la fenêtre fille dans la fonction OnInitialUpdate() on commence par récupérer le pointeur sur la MDI avec la fonction GetParentFrame() pour appeler MDIMaximize( );

((CMDIChildWnd *)GetParentFrame())->MDIMaximize( );

Comment restaurer une fenêtre fille(Child) ?
auteur : Farscape
En passant par les fonctions de la CMDIChildWnd .
A partir de la fenêtre fille dans la fonction OnInitialUpdate() on commence par récupérer le pointeur sur la MDI avec la fonction GetParentFrame() pour appeler MDIRestore( );

((CMDIChildWnd *)GetParentFrame())->MDIRestore( );

Comment récupérer la MDIChild active ?
auteur : Farscape

CMDIFrameWnd::MDIGetActive 
CMDIChildWnd* MDIGetActive( BOOL* pbMaximized = NULL ) const;
Exemple d'application maximiser la child active .
On commence par récupérer le pointeur sur la MainFrame avec AfxGetMainWnd().

BOOL maximized;
CMDIChildWnd* child =((CMDIFrameWnd *)AfxGetMainWnd())->MDIGetActive(&maximized);
if (child && (!maximized))
      child->MDIMaximize();   // ou MDIMaximize(child); 

Comment savoir si une fenêtre fille est iconisée ?
auteur : Farscape
En utilisant la fonction IsIconic() de la classe CWnd.

CWnd::IsIconic
BOOL IsIconic( ) 
const; 
Exemple de restauration d'une MDI iconisée

 BOOL maximized;
   CMDIChildWnd* child =((CMDIFrameWnd *)AfxGetMainWnd())-> MDIGetActive(&maximized);
   if (child && (maximized || child->IsIconic()))
     child->MDIRestore();     // ou ((CMDIFrameWnd *)AfxGetMainWnd())->MDIRestore(child);

Comment activer une fenêtre fille (child)?
auteur : Farscape
En passant par les fonctions de la CMDIChildWnd .
A partir de la fenêtre fille dans la fonction OnInitialUpdate() on commence par récupérer le pointeur sur la MDI avec la fonction GetParentFrame() pour appeler MDIActivate( );

GetParentFrame()->MDIActivate( );

Comment activer et faire passer en premier plan une fenêtre fille (Child)?
auteur : Farscape
En passant par les fonctions de la CMDIChildWnd .
A partir de la fenêtre fille dans la fonction OnInitialUpdate() on commence par récupérer le pointeur sur la MDI avec la fonction GetParentFrame() pour appeler ActivateFrame:

CFrameWnd::ActivateFrame
virtual void ActivateFrame( 
int nCmdShow = ? 1); 
le paramètre nCmdShow correspond à la fonction ShowWindow.

GetParentFrame()->ActivateFrame(SW_RESTORE);
Cette fonction modifie le z order des fenêtres en faisant passer la fenêtre en avant plan.


Comment faire pour qu'un projet MDI soit toujours en avant plan ?
auteur : Farscape
On rajoutera la séquence SetWindowPos dans la fonction OnCreate de la classe CMainFrame juste après les initialisations classiques toolbar dialogbar etc...

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
    return -1;
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
            | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
            !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }
    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
        sizeof(indicators)/sizeof(UINT)))
    {

        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }

    // TODO: Delete these three lines if you don't want the toolbar to
    //  be dockable
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

    // MainFrame Always on Top ! 
    CRect rect;
    GetWindowRect( rect );
    ::SetWindowPos(m_hWnd ,
                    HWND_TOPMOST,
                    rect.left,     
                    rect.top,       
                    rect.Width(),   
                    rect.Height(), 
                    SWP_SHOWWINDOW); 

    return 0;
}

Comment changer la taille d'une View dans un contexte MDI?
auteur : Farscape

CRect  RectFrame;
// Récupération de la taille de la mdi
GetParentFrame()->GetWindowRect(&RectFrame);
// changement de la hauteur sans bouger la fenêtre .
GetParentFrame()->SetWindowPos(NULL,0,0,RectFrame.Width(),lParam,SWP_NOMOVE | SWP_NOZORDER);
où lParam représente ici ma nouvelle hauteur.

BOOL SetWindowPos ( 
const CWnd* pWndInsertAfter, 
int x, 
int y, 
int cx, 
int cy, 
UINT nFlags ); 

Comment mémoriser la position des fenêtres dans une application MFC ?
Créé le 19/09/2005[haut]
auteur : Farscape
Dans une application MFC il n' y a pas de mécanismes standard pour la mémorisation des fenêtres.
Pour remédier à ce problème il faudra mettre en place une sauvegarde de la position et taille de la fenêtre principale (MainFrame) et des fenêtres Filles (MDIChild).

Le code qui suit est une implémentation de ces fonctionnalités avec une classe template permettant l'insertion dans un projet existant sans modifications excessives de code :

// TplMDIFrame.hpp : interface of the CTplMDIFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_TPLMDIFRAME_H__59DC7C67_79D6_4082_A38B_4CD17E8257C1__INCLUDED_)
#define AFX_TPLMDIFRAME_H__59DC7C67_79D6_4082_A38B_4CD17E8257C1__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Farscape : le 22/02/2005 Beta 1.0

// classe de base et traitement sur la MainFrame.
template <class GENERIC_FRAME>
class CTplMDIFrame : public GENERIC_FRAME
{
public:
    CTplMDIFrame()
    {
        m_rectFrame=CRect(0,0,0,0);
        m_bMaximized=FALSE;
        m_bInitPos=false;
        
        SetSectionName();
    }
    //------------------------
    virtual ~CTplMDIFrame(){SaveFramePos();}
    void SetSectionName(const char *szSection="AppPos")
    {
        m_strSection=szSection;
    }
    //------------------------
    void    SaveFramePos()
    {
        MakeSection();
        AfxGetApp()->WriteProfileInt(m_strSection, "Maximized", m_bMaximized);
        AfxGetApp()->WriteProfileBinary(m_strSection, "FrameRect", (BYTE*)&m_rectFrame,sizeof(CRect));
        AfxGetApp()->WriteProfileBinary(m_strSection, "InitialFrameRect", (BYTE*)&m_rectInitialFrame,sizeof(CRect));
    }
    //------------------------
    virtual void MakeSection(){}
    //------------------------
    voidLoadFramePos()
    {
        BYTE* pb = NULL;
        UINT nLen = 0;        
        MakeSection();
        m_bMaximized = AfxGetApp()->GetProfileInt(m_strSection, "Maximized", (int)FALSE);        
        m_rectFrame.SetRect(0,0,0,0);        
        m_rectInitialFrame.SetRect(0,0,0,0);
        if (AfxGetApp()->GetProfileBinary(m_strSection, "FrameRect", &pb, &nLen))
        {
            ASSERT(nLen == sizeof(CRect));
            memcpy(&m_rectFrame, pb, sizeof(CRect));
            delete pb;
        }        
        if (AfxGetApp()->GetProfileBinary(m_strSection, "InitialFrameRect", &pb, &nLen))
        {
            ASSERT(nLen == sizeof(CRect));
            memcpy(&m_rectInitialFrame, pb, sizeof(CRect));
            delete pb;
        }        
        
        CRect rectScreen(0, 0, GetSystemMetrics(SM_CXSCREEN), 
            GetSystemMetrics(SM_CYSCREEN));
        CRect rectInt;
        rectInt.IntersectRect(&rectScreen, &m_rectFrame);
        if (rectInt.Width() < 10 || rectInt.Height() < 10) m_rectFrame.SetRect(0, 0, 0, 0);
    }
    //------------------------
    voidShowMainFrame(int nCmdShow)
    {
        ASSERT(this->IsKindOf( RUNTIME_CLASS(CMDIFrameWnd)));
        
        AfxGetApp()->m_nCmdShow =nCmdShow;
        if (m_bMaximized) AfxGetApp()->m_nCmdShow = SW_SHOWMAXIMIZED;
        ShowWindow(AfxGetApp()->m_nCmdShow);
        UpdateWindow();
    }
    //------------------------
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs)
    {
        if(cs.lpszClass && !m_bInitPos) 
        {
            LoadFramePos();
            m_bInitPos=true;
            if(m_rectFrame.Width() > 0 && m_rectFrame.Height() > 0)
            {
                cs.x  = m_rectFrame.left;
                cs.y  = m_rectFrame.top;
                cs.cx = m_rectFrame.Width();
                cs.cy = m_rectFrame.Height();
            }
        }
        // MainFrame
        if(this->IsKindOf( RUNTIME_CLASS(CMDIFrameWnd)))
        {
            if(!GENERIC_FRAME::PreCreateWindow(cs) ) return FALSE;
        }
        else
        {        
            // child
            if(GENERIC_FRAME::PreCreateWindow(cs) ) return FALSE;
        }
        // TODO: Modify the Window class or styles here by modifying
        //  the CREATESTRUCT cs        
        
        return TRUE;
    }    
    // ---------------------------
    
    CRect &GetInitialRectFrame(){return m_rectInitialFrame;}
    // ---------------------------
    void  SetInitialRectFrame(CRect Rect){m_rectInitialFrame=Rect;}
    // ---------------------------
    void GetWndPos()
    {
        WINDOWPLACEMENT wp;
        wp.length = sizeof(wp);
        GetWindowPlacement(&wp);
        m_rectFrame = wp.rcNormalPosition;
        
    }
    //------------------------
    virtual LRESULT DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
    {        
        if(nMsg==WM_DESTROY )
        {
            m_bMaximized = (GetStyle() & WS_MAXIMIZE);
            GetWndPos();
        }
        if(nMsg==WM_MOVE)
        {
            GetWndPos();
        }
        if(nMsg==WM_SIZE)
        {
            GetWndPos();            
        }
        return GENERIC_FRAME::DefWindowProc( nMsg, wParam,lParam);
    }     
    
    // Attributes
public:
    bool    m_bInitPos;            
    BOOL    m_bMaximized;
    CRect   m_rectFrame;
    CRect   m_rectInitialFrame;
    CString m_strSection;
};
// classe pour les MDIChild.
class CMDIChildEx : public CTplMDIFrame<CMDIChildWnd>
{    
public:
    CMDIChildEx()
    {
        m_nPosCurrent=-1;
        SetSectionName("Child");  
    }
    ~CMDIChildEx()
    {
        POSITION pos=m_ListSection.Find(m_strSection);
        if(pos)      m_ListSection.RemoveAt(pos);        
    }
    //------------------------
    virtual void ActivateFrame( int nCmdShow = -1 )
    {
        if(m_bMaximized ) nCmdShow = SW_MAXIMIZE;
        CMDIChildWnd::ActivateFrame(nCmdShow);
    }   
    virtual void MakeSection()
    {
        CString str;
        str.Format("%s-%d",(const char *)m_strSection,m_nIDHelp);
        m_strSection=str;
        
        if(m_nPosCurrent==-1)
        {
            int i=0;
            while(1)
            {
                str.Format("%s:%d",(char *)(const char *)m_strSection,i);
                if(m_ListSection.Find(str)) i++;
                else
                {
                    m_ListSection.AddTail(str);            
                    break;
                }
            }
            m_nPosCurrent=i;
        }        
        m_strSection=str;
    }
public:
    static CList<CString ,CString&> m_ListSection;
protected:
    int m_nPosCurrent;
    
};
#endif // !defined(AFX_TPLMDIFRAME_H__59DC7C67_79D6_4082_A38B_4CD17E8257C1__INCLUDED_)
// TplMDIFrame.cpp
#include "stdafx.h"
#include "TplMDIFrame.hpp"

CList<CString ,CString&> CMDIChildEx::m_ListSection;
Utilisation: au niveau de la classe CMainframe:

#include "TplMDIFrame.hpp"

class CMainFrame : public CTplMDIFrame<CMDIFrameWnd>
{
..........
au niveau de la classe CChildFrame

#include "TplMDIFrame.hpp"
class CChildFrame : public CMDIChildEx
{
........
au niveau de la classe d'application dans la fonction initInstance :

// The main window has been initialized, so show and update it.
    pMainFrame->ShowMainFrame(m_nCmdShow);
// la ligne du dessous remplace ces deux lignes
//pMainFrame->ShowWindow(m_nCmdShow);
//pMainFrame->UpdateWindow();
au niveau des View il faudra enlever la ligne ResizeParentToFit():

void CTestMdILayoutView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
    
 // ne pas appeler 
//ResizeParentToFit();
}
Fonctionnalités : Ces classes template permettent la gestion de la taille et position de la fenêtre principale ainsi que le mode maximiser de l'application.
Au niveau des fenêtres filles, on retrouve les mêmes fonctionnalités plus la gestion des positions pour plusieurs fenêtres de la même classe.
La différenciations des views se fait grâce à leur numéro d'identifiant dans les ressources.

Ces informations sont stockées dans le .ini de l'application qui ressemblera à ça :

[AppPos]
Maximized=16777216
FrameRect=EIAAAAAAOKAAAAAAEIDAAAAAHNCAAAAA
[Child-129:0]
Maximized=0
FrameRect=HMBAAAAAHABAAAAAKPDAAAAACKCAAAAA
[Child-129:1]
Maximized=0
FrameRect=PPPPPPPPPPPPPPPPNMBAAAAAFABAAAAA
L'application est référencée par AppPos et les fenêtres filles par Child suivi du numéro d'identifiant et le numéro d'appel.

Un exemple complet:
http://farscape.developpez.com/Samples/TestMdiLayout.zip


Comment s'affranchir du mécanisme par défaut pour les titres des fenêtres dans un contexte document/view ?
Créé le 27/11/2005[haut]
auteur : Nourdine Falola
Dans un contexte SDI/MDI, le titre d'une fenêtre est régi par le document auquel elle se rattache. Ce comportement est dû au style FWS_ADDTOTITLE, activé par défaut, du cadre affichant la vue.

Le nom du document est demandé à la création du projet. A l'étape 4 de l'AppWizard, cliquez sur "Advanced..." :

  • le champ "Main frame caption" détermine le début du titre du cadre principal
  • le champ "Doc type name" détermine la racine du nom par défaut du document. Si on ne met rien la racine sera "sans nom".
le nom du document peut aussi être modifié dans le code par l'appel de la fonction CDocument::SetTitle(LPCTSTR lpszTitle).

Le titre sera formaté ainsi :

- SDI : pour le cadre principal : "nom par défaut du document - nom du cadre"

- MDI :
pour le cadre principal :

  • sans document ouvert : "titre cadre principal"
  • avec document ouvert : "titre cadre principal - racine du nom du document actif et n°"
  • avec document ouvert et vue maximisée : "titre cadre principal - [racine du nom du document actif et n°]" pour une vue : "racine du nom du document actif et n°"
On peut vouloir modifier ce mécanisme pour personnaliser le titre d'une vue. Cela peut-être intéressant dans un contexte SDI ou MDI à document à vues multiples. Pour cela, chaque vue doit être associée à une ressource IDR (menu, icône, ...) différente (ce qui donnera lieu à une chaîne par ressource dans la String Table).

1. On modifie la chaîne de la String Table associée à chaque ressource (Comment changer le filtre de l'ouverture de fichiers dans une application MFC ?) :

SDI
ID              Value    Caption
IDR_MAINFRAME   128      Titre main frame\nRacine nom doc par défaut\n\nFichier machin (*.m)\n.m\nM.Document\nM Document
IDR_TATA        129      Titre perso de la 1ère vue\n\n\n\n\n\n
IDR_TITI        130      Titre perso de la 2ème vue\n\n\n\n\n\n
IDR_TOTO        131      Titre perso de la 3ème vue\n\n\n\n\n\n
MDI
ID              Value    Caption
IDR_MAINFRAME   128      Titre main frame\n\nRacine nom doc par défaut\nFichier machin (*.m)\n.m\nM.Document\nM Document
IDR_TATA        129      Titre perso de la 1ère vue\n\n\n\n\n\n
IDR_TITI        130      Titre perso de la 2ème vue\n\n\n\n\n\n
IDR_TOTO        131      Titre perso de la 3ème vue\n\n\n\n\n\n
2. Surcharger la fonction CWnd::PreCreateWindow :

SDI
On surchargera CMainFrame::PreCreateWindow(CREATESTRUCT& cs).

MDI
BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    // le titre de la fenêtre ne correspond plus au titre du document
    // si la ressource ne définit pas le champ titre, la fenêtre aura
    // comme titre "sans nom"
    cs.style &= ~(LONG)FWS_ADDTOTITLE;

    // Appelle la fonction de la classe mère
    return CMDIChildWnd::PreCreateWindow(cs);
}


Comment griser le bouton et le menu fermeture d'une fenêtre MDI ?
Créé le 20/05/2006[haut]
auteur : Farscape
Pour empêcher la fermeture d'une fenêtre il faut intercepter la commande SC_CLOSE comme dans faq Comment intercepter la fermeture de l'application ?.
pour griser l'option fermeture du menu système et griser la croix de la fenêtre on procédera comme suit:

// exemple à partir de la view.
CMenu *pSysMenu =GetParentFrame()->GetSystemMenu(FALSE);
ASSERT(pSysMenu != NULL);

pSysMenu->EnableMenuItem(SC_CLOSE,MF_BYCOMMAND  |MF_GRAYED   ); 
On commence par récupérer le menu système de la MDI, ensuite on règle le statut grisé avec la fonction EnableMenuItem pour l'identifiant SC_CLOSE.


Comment créer une fenêtre MDI que l'on ne peut bouger ?
Créé le 20/05/2006[haut]
auteur : Farscape
Il faut intercepter le message WM_WINDOWPOSCHANGING sur la MDIChild. Exemple:

void CChildFrame::OnWindowPosChanging(WINDOWPOS* lpwndpos) 
{ 
   if(!m_rect.IsRectEmpty())   // empeche de bouger... 
   { 
      lpwndpos->x=m_rect.left; 
      lpwndpos->y=m_rect.top;    
      CRect rectBarPos; 
      static_cast<CMainFrame *>(AfxGetMainWnd())->m_wndToolBar.GetWindowRect(&rectBarPos); 
      lpwndpos->y-=rectBarPos.Height(); 

   } 
   CMDIChildWnd::OnWindowPosChanging(lpwndpos); 

   // TODO: Add your message handler code here 
}
//------------------------------------------------------------ 
void CChildFrame::OnSize(UINT nType, int cx, int cy) 
{ 
   CMDIChildWnd::OnSize(nType, cx, cy); 
   if(m_rect.IsRectEmpty()) // position initiale 
   { 
      GetWindowRect(&m_rect); 
      AfxGetMainWnd()->ScreenToClient(&m_rect); 
   } 
   // TODO: Add your message handler code here 
}
Essai réalisé avec Visual 2005.
Il se peut que le message ne soit pas implémenté avec VC 6.
Il faudra le rajouter manuellement


Comment accéder à la vue active dans un projet SDI ?
Créé le 22/01/2007[haut]
auteur : Farscape
Le cas typique est l'accès de la vue à partir d'une boîte de dialogue.

On pourra procéder comme suit :

 BOOL CMyDialog::OnInitDialog() 
{
    CDialog::OnInitDialog();
    
    // TODO: Add extra initialization here

    // acces à la seule vue active 
    CView *pView=static_cast<CFrameWnd *>(AfxGetMainWnd())->GetActiveView();
    // transformation sur la classe de la vue.
    CSampleSDIView * pSDIView= static_cast<CSampleSDIView *>(pView);

    pSDIView->m_Edit.SetWindowText("essai");
    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}
pourquoi ne pas faire GetParent() ?, hé bien dans un projet SDI GetParent() dans la boîte de dialogue renvoie le pointeur sur la CMainFrame.
Voir aussi faq Comment récupérer la fenêtre parent dans une boîte de dialogue ?

Note: la méthode pourra aussi être appliquée sur un projet MDI.

lien : faq Comment récupérer la fenêtre parent dans une boîte de dialogue ?


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.