IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Classes Fenêtres et FrameWork > Gestion du framework
        Comment faire pour que dans une boucle de traitement l'application ne semble pas figée ?
        Comment récupérer le pointeur sur la fenêtre active ?
        Comment savoir s'il existe une instance d'une View en MDI ?
        Comment changer le filtre de l'ouverture de fichiers dans une application MFC ?
        Comment éviter le stockage d'objet CMultiDocTemplate pour l'appel des fenêtres dans un projet MDI ?
        Comment limiter la taille minimum d'une Application ?
        Comment intervenir sur le positionnement de la souris ?
        Comment éviter d'avoir la sélection de fenêtre à ouvrir sur la commande ID_FILE_NEW dans un projet MDI avec plusieurs fenêtres ?
        Comment éviter le lancement automatique d'une fenêtre au départ de l'application MDI ?
        Comment intercepter le message ID_FILE_SAVE ?
        Comment désactiver/activer la statusbar ou la toolbar ?
        Comment changer la taille d'une View dans un contexte SDI?
        Comment faire une application MDI/SDI sans bouton dans la barre des tâches Windows ?
        Comment récupérer la surface client d'une CFormView à son initialisation ?
        Comment personnaliser la création d'une Frame en SDI/MDI ?
        Pourquoi l'appel à AfxGetMainWnd peut provoquer une erreur avec Visual .Net ?
        Comment empêcher une fenêtre fille d'être déplacée dans la surface de travail de l'application?
        Comment avoir une surface de travail dynamique sur la MainFrame ?
        Comment créer dynamiquement une vue dans une application SDI ?
5.7.1. CSplitterWnd (6)
                Comment faire pour séparer une fenêtre en deux ?
                Comment mettre en place un splitter dans un projet SDI ?
                Comment figer un splitter ?
                Comment communiquer entre des vues d'un splitter ?
                Comment supprimer une vue dans un CSplitterWnd ?
                Comment implémenter plusieurs splitters dans un projet SDI ?



Comment faire pour que dans une boucle de traitement l'application ne semble pas figée ?
auteur : Farscape
Il faut laisser à l'application le temps de traiter les messages sinon dés que l'on bouge la fenêtre ou si elle recouverte par une autre application il n'y a plus de reconstruction possible .
Solution intégrer dans sa boucle l'appel de la fonction suivante qui pourrait être une fonction static de la classe d'application par exemple :

/*static */void CMyApp ::PumpMessages() 
{ 
   // Handle dialog messages 
    MSG msg; 
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
        if (!AfxGetApp()->PreTranslateMessage(&msg)) 
      { 
         ::TranslateMessage(&msg); 
         ::DispatchMessage(&msg); 
     }            
     AfxGetApp()->OnIdle(0);   // updates user interface 
    AfxGetApp()->OnIdle(1);   // frees temporary objects 
    } 
}

Comment récupérer le pointeur sur la fenêtre active ?
auteur : Farscape

((CMDIFrameWnd *)AfxGetMainWnd())->GetActiveFrame( )->GetActiveView();
Récupération de la mainFrame ,puis de la MDI Active .
Et enfin de la view dans la MDI active.
Le test doit être découpé pour éviter un problème si il n'y a pas MDI active !

CView* CFrameWnd::GetActiveView( ) const;

Comment savoir s'il existe une instance d'une View en MDI ?
Créé le 20/05/2006[haut]
auteur : Farscape
La réponse s'appuie sur les Q/R de la faq :
faq Comment parcourir dans un contexte MDI toutes les fenêtres de l'application ?
faq Comment activer et faire passer en premier plan une fenêtre fille (Child)?

La fonction ci-dessous cherche une instance d'une classe fenêtre en l'identifiant par sa signature.

CWnd *FindInstanceView(CRuntimeClass *pViewClass)
{
    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(pViewClass))
                    {
                        return pView;
                    }                    
                }
            }
        }
    }
    return NULL;
}
Utilisation: recherche d'une instance de la classe CTestMdiView .
si la fenêtre est trouvée on la refait passer en avant plan.

CTestMdiView *pView;
if((pView=static_cast<CTestMdiView *>(FindClassView(RUNTIME_CLASS(CTestMdiView)))))
{
TRACE("\nInstance de la classe trouvée");
static_cast<CMDIChildWnd *>(pView->GetParentFrame())->ActivateFrame(SW_RESTORE);
}

Comment changer le filtre de l'ouverture de fichiers dans une application MFC ?
auteur : Farscape
A chaque nIDResource associée à un document template on trouve dans l'éditeur de ressources dans la « stringtable » la chaîne d'ouverture pour le document.

Exemple:
Pour l'id IDR_TESTMDTYPE on pourra avoir :

\nExts\nExts\nFichiers (*.txt)\n.txt\nExts.Doc\nExts Doc
Description :

IDR_TESTMDTYPE <windowTitle>\n<docName>\n<fileNewName>\n
                    <filterName>\n <filterExt>\n<regFileTypeID>\n
                    <regFileTypeName>\n <filterMacExt(filterWinExt)>\n
                    <filterMacName(filterWinName)>

IDR_TESTMDTYPE \nExts\nExts\nFichiers (*.txt ;*.doc)\n.txt;
                                  .doc\Exts.Document.1\nExts Document\nExts\nExts Fichiers

      <windowTitle>           Exts
      <docName>              Exts
      <fileNewName>        Exts
      <filterName>             Fichiers (*.txt)
      <filterExt>                  . txt
      <regFileTypeId>        Exts.Document.1
      <regFileTypeName>  Exts Document
      <filterMacExt>           Exts
      <filterMacName>      Exts Fichiers

 <item> voir Note MSDN:</item>
<b>INFO: Format of the Document Template String
Q129095
</b>

CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_TESTMDTYPE,
RUNTIME_CLASS(CTestMdiDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CTestMdiView));
AddDocTemplate(pDocTemplate);
A l'ouverture j'aurai bien : Fichiers *.txt
Pour gérer le multi documents à l'ouverture c'est plus compliqué
voir note MSDN:

<b>HOWTO: How to Support Two File Extensions per MFC Document Type
Q141921</b>

Comment éviter le stockage d'objet CMultiDocTemplate pour l'appel des fenêtres dans un projet MDI ?
auteur : Farscape
Dans un projet classique on a besoin de l'objet CMultiDocTemplate pour créer les fenêtres avec la commande suivante :

// CMultiDocTemplate * m_pTplEditView; dans le header.
m_pTplEditView->OpenDocumentFile(NULL) ;
Comment faire pour éviter la déclaration de données membres dans la classe d'application ?
Je propose la solution suivante :

  • Redéfinir une classe dérivée de CMultiDocTemplate.
  • Déclarer une fonction d'ouverture d'une fenêtre en fonction de la signature de la classe fenêtre (runtime).
La création pourra s'écrire de la manière suivante:

// CTestMdiApp message handlers
void CTestMdiApp::OnFileNew() 
{
      // TODO: Add your command handler code here
       OpenDocumentFile(RUNTIME_CLASS(CTestMdiView));
}
A la place de :

void CTestMdiApp::OnFileNew() 
{
      // TODO: Add your command handler code here
       m_pTplEditView->OpenDocumentFile(NULL) ;
}
Implémentation:

// header
class CExMultiDocTemplate : public CMultiDocTemplate
{
    DECLARE_DYNAMIC(CExMultiDocTemplate)
    // Constructors
public:
   CExMultiDocTemplate(UINT nIDResource,
                       CRuntimeClass* pDocClass,
                       CRuntimeClass* pFrameClass,
                       CRuntimeClass* pViewClass):
   CMultiDocTemplate(nIDResource,pDocClass,pFrameClass,pViewClass){}

   CRuntimeClass* GetDocClass()   {return m_pDocClass;}
   CRuntimeClass* GetFrameClass() {return m_pFrameClass;}
   CRuntimeClass* GetViewClass()  {return m_pViewClass;}
   UINT GetnIDResource()          {return m_nIDResource;}
};

// .cpp
IMPLEMENT_DYNAMIC(CExMultiDocTemplate,CMultiDocTemplate)
CDocument *CTestMdiApp::OpenDocumentFile(CRuntimeClass *pClassView,
                                         LPCTSTR lpszPathName/*=NULL*/, 
                                         BOOL bMakeVisible /*= TRUE*/ )
{
    // parcourir tous les templates
    CDocTemplate* pTemplate;
    POSITION pos = GetFirstDocTemplatePosition();
    while (pos != NULL)
    {
        pTemplate = GetNextDocTemplate(pos);
        ASSERT(pTemplate);
        if(pTemplate->IsKindOf(RUNTIME_CLASS(CExMultiDocTemplate)))
        {
            if(((CExMultiDocTemplate *)pTemplate)->GetViewClass()==pClassView)
                 return pTemplate->OpenDocumentFile(lpszPathName,bMakeVisible);
        }
    }
    return NULL;
}
utilisation :

CExMultiDocTemplate *pTemplate;
pTemplate = new CExMultiDocTemplate(
IDR_TESTMDTYPE,
RUNTIME_CLASS(CTestMdiDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CTestMdiView));
AddDocTemplate(pTemplate);

pTemplate= new CExMultiDocTemplate(
                            IDR_TESTMDTYPE,
                            RUNTIME_CLASS(CTestMdiDoc),
                            RUNTIME_CLASS(CChildFrame), // custom MDI child frame
                            RUNTIME_CLASS(CEditView));
AddDocTemplate(pTemplate);
La classe CExMultiDocTemplate permet l'accès aux données membres de la classe de base, dans notre cas c'est le runtime de la classe fenêtre qui nous intéresse.
La fonction OpenDocumentFile parcourt tous les documents templates et recherche celui qui dispose de la signature fenêtre désirée pour appeler ensuite OpendocumentFile.
Donc plus besoin de variables pour stocker les documents templates et un appel simplifié par signature de classe pour créer la fenêtre.


Comment limiter la taille minimum d'une Application ?
auteur : Farscape
En interceptant le message WM_GETMINMAXINFO.
Et en consultant les données de la structure MINMAXINFO,
Exemple limitation de la taille minimum de l'application à 320 pixels de large et 240 de haut.

void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) 
{ 
   // TODO: Add your message handler code here and/or call default            
    lpMMI->ptMinTrackSize.x = 320; 
    lpMMI->ptMinTrackSize.y = 240;                 
    CMDIFrameWnd::OnGetMinMaxInfo(lpMMI); 
}  

Comment intervenir sur le positionnement de la souris ?
auteur : Farscape
En utilisant la fonction SetCursorPos.

BOOL SetCursorPos(
  int X,  // horizontal position
  int Y   // vertical position
);
Exemple en modifiant la position de la souris lors de son déplacement à la réception du message WM_MOUSEMOVE.

void CTestMdiView::OnMouseMove(UINT nFlags, CPoint point)
{
   // TODO: Add your message handler code here and/or call default

   if(!m_bMouseSetPos) // pour éviter la réentrance dans le message !
   {      
      CPoint pt=point;
      pt.x = 100;          // fixer x a 100 pixels coté client 
      ClientToScreen(&pt); // conversion en coordonnées fenêtre
      ::SetCursorPos(pt.x,pt.y); // fixe la position de la souris
      m_bMouseSetPos=true;    // initialise le flag 
   }
   else m_bMouseSetPos=false; // reset du flag 

   CFormView::OnMouseMove(nFlags, point);
}
m_bMouseSetPos=false; // à initialiser dans le constructeur. 

Comment éviter d'avoir la sélection de fenêtre à ouvrir sur la commande ID_FILE_NEW dans un projet MDI avec plusieurs fenêtres ?
auteur : Farscape
Lorsqu'on a défini plusieurs objets de la classe CMultiDocTemplate dans InitInstance à l'appel la commande ID_FILE_NEW une fenêtre apparaît avec la liste des différents noms de documents disponibles.
Pour éviter cela il suffit de redéfinir la commande ID_FILE_NEW de la classe d'application et d'appeler l'ouverture de la fenêtre qui nous convient :

BEGIN_MESSAGE_MAP(CTestMdiApp, CWinApp)
//{{AFX_MSG_MAP(CTestMdiApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_COMMAND(ID_FILE_NEW, OnFileNew) // redéfinition par classWizard
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

// CTestMdiApp message handlers
void CTestMdiApp::OnFileNew() 
{
    // TODO: Add your command handler code here
    m_pTplEditView->OpenDocumentFile(NULL) ;
}

Comment éviter le lancement automatique d'une fenêtre au départ de l'application MDI ?
auteur : Farscape
Il suffira de mettre en commentaire la séquence suivante contenue dans la fonction InitInstance de la classe d'application :

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

Comment intercepter le message ID_FILE_SAVE ?
Mise à jour le 07/07/2008[haut]
auteur : Farscape
Dans une application MFC la gestion des documents lecture sauvegarde etc.. est prise en charge par un objet dérivé de la classe CDocument pour le document template concerné (voir CDocTemplate ).
Il suffira donc d'intercepter le message ID_FILE_SAVE sur la classe document par l'intermédiaire de « ClassWizard »
Si d'aventure on souhaitait l'intercepter au niveau de la mainframe on récupérera la notification avec la fonction OnCommand :

BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class
    if(LOWORD(wParam)==ID_FILE_SAVE)
    {
        AfxMessageBox("Msg:ID_FILE_SAVE");
    }
    return CMDIFrameWnd::OnCommand(wParam, lParam);
}
Attention tout de même de savoir quel est le document concerné dans un contexte MDI.
Avec par exemple la fonction GetActiveDocument() :

CFrameWnd::GetActiveDocument
virtual CDocument* GetActiveDocument( ); 

Comment désactiver/activer la statusbar ou la toolbar ?
auteur : Farscape
En simulant l'appel des commandes : ID_VIEW_TOOLBAR et ID_VIEW_STATUS_BAR comme sur le menu standard: "affichage" de l'application.
A partir de la view on récupère le pointeur sur la mainframe, puis on désactive la toolbar et la statusbar par l'envoi d'un message WM_COMMAND.
Les mêmes appels feront réapparaître les barres comme dans le menu...

// dans la view sur l'appel d'un bouton par exemple.
CMainFrame * pMain=(CMainFrame *)AfxGetMainWnd();
pMain->SendMessage(WM_COMMAND, ID_VIEW_TOOLBAR, 0L);
pMain->SendMessage(WM_COMMAND, ID_VIEW_STATUS_BAR,0L);

Comment changer la taille d'une View dans un contexte SDI?
auteur : Farscape
Dans le cas d'un projet SDI il faut faire le travail sur la mainframe.
Exemple sur l'action d'un bouton situé dans une CFormView:

void CTestSDIView::OnButton1()
{
   // TODO: Add your control notification handler code here
    // Récupération de la taille de la mainframe
    CRect  RectFrame;
    AfxGetMainWnd()->GetWindowRect(&RectFrame);
    // changement de taille +100 en hauteur et largeur.
    AfxGetMainWnd()->SetWindowPos(NULL,0,0,
                                       RectFrame.Width()+100,
                                       RectFrame.Height()+100,
                                       SWP_NOMOVE | SWP_NOZORDER);
}

Comment faire une application MDI/SDI sans bouton dans la barre des tâches Windows ?
auteur : Farscape
La technique utilisée est différente de celle de la boîte de dialogue, on fournit ici une fenêtre parent de style popup à la mainframe.

CMainFrame::~CMainFrame()
{
    if (m_HideWnd.m_hWnd != NULL) m_HideWnd.DestroyWindow();
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    //CWnd m_HideWnd ; comme donnée membre de la classe CMainFrame.

    if (!CFrameWnd::PreCreateWindow(cs))
    return FALSE;

    if(m_HideWnd.m_hWnd==NULL)
   {
        if (!m_HideWnd.CreateEx(0, AfxRegisterWndClass(0), _T(""), WS_POPUP,
       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
       NULL, 0))
      return FALSE;
   }
   cs.hwndParent = m_HideWnd.m_hWnd;
   return TRUE;
}

Comment récupérer la surface client d'une CFormView à son initialisation ?
auteur : Farscape
Pour préciser le sujet:
Il arrive parfois que l'on ait besoin de créer dynamiquement des contrôles à l'initialisation de la CFormView ,
Dans ce contexte, il s'avère utile de connaître la surface disponible pour placer au mieux les contrôles.
L'endroit le plus approprié étant la fonction OnInitialUpdate .
Pour avoir un résultat correct avec la fonction GetClienRect, il faudra d'abord procéder à une demande de recalcule de la taille de la frame.

GetParentFrame()->RecalcLayout(); 
ResizeParentToFit(); 
CRect Rect ;
GetClientRect(&Rect) ;
ResizeParentToFit assure que la dimension de la vue soit bien réglée.
L'appel à RecalcLayout est indispensable avant ResizeParentToFit (risque d'assertion), il assure lors du dimensionnement de la frame le rafraîchissement des barres de contrôles.


Comment personnaliser la création d'une Frame en SDI/MDI ?
Créé le 27/11/2005[haut]
auteur : Nourdine Falola
En surchargeant la fonction membre virtuelle CWnd::PreCreateWindow pour modifier la structure CREATESTRUCT, qui définit les paramètres d'initialisation de la fenêtre (i.e. du cadre), avant la création de celle-ci.
typedef struct tagCREATESTRUCT {
    LPVOID lpCreateParams;
    HINSTANCE hInstance;
    HMENU hMenu;
    HWND hwndParent;
    int cy;
    int cx;
    int y;
    int x;
    LONG style;
    LPCTSTR lpszName;
    LPCTSTR lpszClass;
    DWORD dwExStyle;
} CREATESTRUCT, *LPCREATESTRUCT;
(cx,cy) : largeur et hauteur de la nouvelle fenêtre, en pixels
(x,y) : coordonnées du coin supérieur gauche de la fenêtre, en pixels.
style : style de la nouvelle fenêtre (Available styles,Frame-window styles) dwExStyle : style étendu de la nouvelle fenêtre
Exemple pour un projet SDI :

Le style par défaut est une combinaison de WS_OVERLAPPEDWINDOW et FWS_ADDTOTITLE. FWS_ADDTOTITLE indique au framework d'ajouter au titre de la fenêtre le titre du document.
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    // Fenêtre sans boutons min/max et bords dimensionnables
    cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER;

    // Dimensionne au 1/3 de la taille de l'écran la fenêtre, et la centre
    cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
    cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3;
    cs.y = ((cs.cy * 3) - cs.cy) / 2;
    cs.x = ((cs.cx * 3) - cs.cx) / 2;

    // Appelle la fonction de la classe mère
    return CFrameWnd::PreCreateWindow(cs);
}
Exemple pour un projet MDI :

Le style par défaut est une combinaison de WS_CHILD, WS_OVERLAPPEDWINDOW et FWS_ADDTOTITLE.
BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    // Crée une fenêtre sans bouton Maximiser
    cs.style &= ~WS_MAXIMIZEBOX;

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

Pourquoi l'appel à AfxGetMainWnd peut provoquer une erreur avec Visual .Net ?
Créé le 22/01/2007[haut]
auteur : Farscape

Il y a bien une différence dans la fonction AfxGetMainWnd() à partir de VC7 et les versions précédentes..

_AFXWIN_INLINE CWnd* AFXAPI AfxGetMainWnd()
    { CWinThread* pThread = AfxGetThread();
        return pThread != NULL ? pThread->GetMainWnd() : NULL; }

Cette fonction appel la fonction AfxGetThread(), et cette fonction est implémentée différemment à partir de VC7...
en VC7 :

CWinThread* AFXAPI AfxGetThread()
{
  // check for current thread in module thread state
  AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  CWinThread* pThread = pState->m_pCurrentWinThread;
  return pThread;
}


En VC6.0 :

CWinThread* AFXAPI AfxGetThread()
{
  // check for current thread in module thread state
  AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  CWinThread* pThread = pState->m_pCurrentWinThread;
  //if no CWinThread for the module, then use the global app
  if (pThread == NULL)
      pThread = AfxGetApp();
  return pThread;
}

donc on peux remplacer notre appel de AfxGetMainWnd() par :


AfxGetApp()->GetMainWnd();


pourquoi ce code a été modifié reste un mystère ...


Comment empêcher une fenêtre fille d'être déplacée dans la surface de travail de l'application?
Créé le 17/09/2007[haut]
auteur : Farscape
Pour empêcher dans un contexte MDI de déplacer une fenêtre fille dans la surface de travail de l'application on interceptera 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
}
Sur le premier WM_SIZE de la fenêtre on mémorise sa position et sur le message WM_WINDOWPOSCHANGING on la restitue.


Comment avoir une surface de travail dynamique sur la MainFrame ?
Créé le 17/09/2007[haut]
auteur : Farscape
L'espace de travaille alloué à la mainframe dans le mode maximisé dépend directement de la résolution de l'écran,
Pour disposer d'une surface plus grande on rajoutera les styles WS_VSCROLL | WS_HSCROLL à la création de la MainFrame.
Dés qu'une fenêtre sera poussée ou créer en dehors de la surface normale d'affichage, les ascenseurs apparaitront agrandissant du même coup notre espace de travail.

Comment procéder :
Surchargez avec l'assistant la fonction virtuelle PreCreateWindows et rajouter les styles pour les barres d'ascenseurs.

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs    
    cs.style |=(WS_VSCROLL | WS_HSCROLL);    
    return CMDIFrameWnd::PreCreateWindow(cs);
}

Comment créer dynamiquement une vue dans une application SDI ?
Créé le 07/07/2008[haut]
auteur : Farscape
On rajoutera le code suivant à la classe CMainFrame créée :

//CArray <CView *,CView *> m_arView; a déclarer comme variable membre de la classe.
//-----------------------------------------------
void CMainFrame::ActiveFormView(int n)
{
	VERIFY(n<m_arView.GetCount());

	CView* pActiveView = GetActiveView();
	CView *pNewView = m_arView[n];

    UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
    ::SetWindowLong(pActiveView->m_hWnd, GWL_ID,
    ::GetWindowLong(pNewView->m_hWnd, GWL_ID));
    ::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);

    pActiveView->ShowWindow(SW_HIDE);
    pNewView->ShowWindow(SW_SHOW);
    SetActiveView(pNewView);
    RecalcLayout();
    pNewView->Invalidate();
}
//-----------------------------------------------
CView *CMainFrame::AddView(CRuntimeClass *pClassView)
{
	CView* pView = static_cast<CView *>(pClassView->CreateObject());
	CView* pActiveView = GetActiveView();

	if(!m_arView.GetCount()) m_arView.Add(pActiveView);

    CDocument* pCurrentDoc = GetActiveDocument();
    
    CCreateContext newContext;
    newContext.m_pNewViewClass = NULL;
    newContext.m_pNewDocTemplate = NULL;
    newContext.m_pLastView = NULL;
    newContext.m_pCurrentFrame = NULL;
    newContext.m_pCurrentDoc = pCurrentDoc;
    
    CRect rect(0, 0, 0, 0); 
    pView->Create(NULL, NULL,(AFX_WS_DEFAULT_VIEW & ~WS_VISIBLE),rect, this,
				AFX_IDW_PANE_FIRST + m_arView.GetCount(), &newContext);
	m_arView.Add(pView);
	pView->OnInitialUpdate();
	return pView;
}
J'ai implémenté deux méthodes :
Une pour la création de la vue d'après un Runtime de classe fourni, l'autre pour activer la vue.
La vue 0 est la vue principale. L'ensemble des vues est stocké dans un CArray.
Utilisation:
dans InitInstance je demande la création d'une vue:


	// La seule fenêtre a été initialisée et peut donc être affichée et mise à jour
	m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateWindow();
	// appelle DragAcceptFiles uniquement s'il y a un suffixe
	//  Dans une application SDI, cet appel doit avoir lieu juste après ProcessShellCommand
	static_cast<CMainFrame*>(m_pMainWnd)->AddView(RUNTIME_CLASS(CEditView));
Dans mon exemple j'ai ajouté une CEditView. Pour procéder à l'activation on appellera ActiveFormView:

void CMainFrame::OnFenetre1()
{
	// TODO: Add your command handler code here
	ActiveFormView(0);
}
void CMainFrame::OnFenetre2()
{
	// TODO: Add your command handler code here
	ActiveFormView(1);
}



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.