Часто задаваемые вопросы и ответы по C/C++/Visual C++
Последнее обновление: 27.08.2003
FAQ по C/C++/Visual C++
Работа с сетью
Список фреймов в MDI приложении
Составители: SUnteXx, Leprecon
Список фреймов в MDI приложении
A: (Leprecon)
Оригинальная ссылка: нету

Чтобы сделать перебор всех фреймов в приложении, нужно перебрать все документы. В каждом из них перебрать все виды и получить родительский фрэйм для каждого вида. Проблема в том, что в одном фрэйме может быть несколько видов, разделенных сплиттером к примеру. В этом случае этот фрейм попадется нам несколько раз. Запоминать все фрэймы и сравнивать с текущим не самая лучшая идея. Но в MFC все фрэймы одного документа пронумерованы и номер фрэйма находится в переменной:
int CFrameWnd::m_nWindowЭта переменная принимает следующие значения:
-1 - неизвестное окно.
0 - единственный фрэйм у документа.
1, 2, и т.д. - номер фрэйма, если у документа их несколько.

int CountFrames()
{
    CDocManager* pDocManager = AfxGetApp()->m_pDocManager;
    
    int nFrameCount = 0;
    POSITION posTemplate = pDocManager->GetFirstDocTemplatePosition();
    while(posTemplate)
    {
        CDocTemplate* pTemplate = pDocManager->GetNextDocTemplate(posTemplate);
        
        POSITION posDoc = pTemplate->GetFirstDocPosition();
        while(posDoc)
        {
            CDocument* pDoc = pTemplate->GetNextDoc(posDoc);

            // Пометим все видимые фрэймы как непосчитанные.
            POSITION posView = pDoc->GetFirstViewPosition();
            while(posView)
            {
                CView* pView = pDoc->GetNextView(posView);
                if (pView->IsWindowVisible())   // Не считаем невидимые окна.
                {
                    CFrameWnd* pFrame = pView->GetParentFrame();
                    if (pFrame != NULL) pFrame->m_nWindow = -1; 
                }
            }

            // Считаем фрэймы.
            int nFrames = 0;
            posView = pDoc->GetFirstViewPosition();
            while(posView)
            {
                CView* pView = pDoc->GetNextView(posView);
                if (pView->IsWindowVisible())   // Не считаем невидимые окна.
                {
                    CFrameWnd* pFrame = pView->GetParentFrame();
                    if (pFrame != NULL && pFrame->m_nWindow == -1) 
                    {
                        // Пометим фрэйм как подсчитанный.
                        // Номер фрэйма должен быть больше нуля.
                        pFrame->m_nWindow = ++nFrames;

                        // Вот сюда можно вставить какие-то действия над фрэймом.
                        // pFrame->DoSomething();
                    }
                }
            }

            // Если открытый фрэйм для этого документа один, надо пометить его нулем.
            if(nFrames == 1)
            {
                posView = pDoc->GetFirstViewPosition();
                while(posView)
                {
                    CView* pView = pDoc->GetNextView(posView);
                    if (pView->IsWindowVisible())  // Не считаем невидимые окна.
                    {
                        CFrameWnd* pFrame = pView->GetParentFrame();
                        if (pFrame != NULL) 
                        {
                            pFrame->m_nWindow = 0; 
                            // Единственный открытый фрэйм нельзя закрывать без сохранения.
                            // MFC закрывает фрэймы помеченные не нулем без сохранения.
                        }
                    }
                }
            }

            nFrameCount += nFrames;
        }
    }

    return nFrameCount;
}
Примечание:
в классе документа есть функция подсчета фрэймов.
void CDocument::UpdateFrameCounts();Идея взята из этой функции.

Если есть какие-то замечания, предложения или что-то еще, то пишите:
leprecon@pisem.net.
Содержание Обсудить на форуме « Предыдущая статья | Следующая статья »
Перейти к FAQ:  
FAQ составлен по материалам Форума на Исходниках.Ру.
Copyright © 2002 by Sources.ru. All rights reserved.