Опубликован: 17.08.2010 | Доступ: свободный | Студентов: 999 / 59 | Оценка: 4.11 / 3.89 | Длительность: 29:38:00
Самостоятельная работа 19:

Модальные окна страниц свойств MFC

Отключение вкладок

Иногда может потребоваться отключить (сделать недоступными - Disabled ) некоторые вкладки окна свойств. Прямых способов отключения вкладок не существует, поэтому рассмотрим обходные пути решения этой задачи. Для этого нужно выполнить следующие действия:

  1. Создать переменную для хранения индекса текущей вкладки
  2. Создать массив переменных для хранения индексов всех отключенных в данный момент вкладок
  3. Создать обработчик уведомляющего сообщения TCN_SELCHANGING или TCN_SELCHANGE позволяющего выяснить индекс текущей вкладки
  4. Разместить в этом обработчике код, принимающий решение о необходимости активизации вкладки
  5. В качестве альтернативы можно воспользоваться сообщением
Создание переменной хранения индекса текущей вкладки
  • Добавьте в конец объявления класса CFindSheet в файле FindSheet.h следующий код
    Объявление переменной хранения индекса текущей вкладки
    class CFindSheet : public CPropertySheet
    {
    .............................
    protected:
      int m_iLastActivePage;
    };
Создание массива индексов отключенных вкладок

В следующих двух таблицах приведены классы массивов, поддерживаемые MFC, и описание их общедоступных методов

Классы массивов MFC
Класс Описание
CArray Шаблонный класс для создания пользовательских классов массивов
CByteArray Массив с данными типа байт
CDWordArray Массив с данными типа DWORD (двойное слово)
CObArray Массив может содержать классы, производные от класса CObject
CPtArray Массив указателей на любые объекты и типы данных
CStringArray Массив объектов типа CString
CUIntArray Массив данных типа UINT ( unsigned int )
CWordArray Массив данных типа WORD (слово)
Методы классов массивов MFC
Класс Описание
array[int index] Оператор ображения к значению элемента массива по его индексу. Индексация массива начинается с нуля
array.GetAt(int index) Возвращает элемент массива по его индексу. Индексация массива начинается с нуля
array.SetAt(int index, element) Записывает элемент массива по его индексу. Тип данных записываемого элемента должен соответствовать типу данных всего массива. Вызов функции не приводит к росту количества элементов массива.
array.InsertAt(int index, element) Вставляет новый элемент перед элементом index. Размерность массива увеличивается на единицу.
array.Add(element) Добавляет новый элемент в конец массива. Добавляемый элемент должен иметь тип данных всего массива.
array.RemoveAt(int index, int count=1) Удаляет count элементов, начиная с позиции index. Если второй аргумент не указан, то удаляется один элемент.
array.RemoveAll() Удаляет все элементы массива и присваивает свойству количества элементов массива значение ноль.
В массивах классов CObArray и CPtArray элементы как объекты не удалаются. Из массивов удаляются только указатели на объекты. При использовании функций RemoveAt() и RemoveAll() необходимо сначала удалить сами объекты, а затем удалить из массива их указатели.
array.GetSize() Возвращает количество элементов массива.
array.GetCount() Возвращает количество элементов массива.
array.GetUpperBound() Возвращает индекс последнего элемента массива.
array.SetSize(int iNewSize, iGrowBy) Управляет размером массива.
array.Copy(source) Копирует source в array
array.Append(source) Присоединяет source в конец array
В случае с массивами классов CObArray и CPtArray функции Copy() и Append() копируют в массив указатели, а не сами объекты. В результате, изменение значения объекта в одном из массивов приведет к изменению значения соответствующего объекта в другом массиве. Кроме того, при удалении элемента в одном из массивов указатель в другом массиве станет недействительным.

Создадим стандартный массив MFC -класса CUIntArray, в котором будут содержаться индексы всех вкладок окна свойств, заблокированных в данный момент.

  • Добавьте в конец объявления класса CFindSheet в файле FindSheet.h следующий код
    Создание массива индексов отключенных вкладок
    class CFindSheet : public CPropertySheet
    {
    .....................................................
    protected:
      int m_iLastActivePage;
      CUIntArray m_arrDisabledPages;
    };
Добавление функции-члена, отключающей определенные вкладки

Добавим в класс CFindSheet функцию-член, позволяющую отключать определенные вкладки. Подлежащие отключению вкладки указаны в передаваемом этой функции аргументе переменной длины ( vararg ), представляющем собой список с завершающим терминатором -1. Эта функция добавляет переданные индексы вкладок в массив m_arrDisabledPages, затем маркирует вкладку присоединением к ее названию текста "-Disabled".

Эту дополнительную работу с добавлением маркера "-Disabled" нужно выполнять потому, что не существует способа по настоящему сделать вкладку недоступной с помощью изменения ее цвета на серый. Поэтому Microsoft рекомендует просто добавлять к заголовку вкладки маркирующий текст.

  • Выделите в панели Class View класс CFindSheet и вызовите мастер добавления функций, который заполните так

  • Нажмите кнопку Add, затем кнопку Finish

    Мастер добавит заготовку в конец файла FindSheet.cpp, а в описание класса добавит прототип функции.

  • Исправьте прототип и заголовок функции для возможности передачи аргументов переменной длины, чтобы они смотрелись так
    Правка в файле FindSheet.h
    class CFindSheet : public CPropertySheet
    {
    ...............................................
    public:
      // Отключение вкладок
      void DisablePage(int iFirstPage, ...);
    };
    Правка в файле FindSheet.cpp
    // Отключение вкладок
    void CFindSheet::DisablePage(int iFirstPage, ...)
    {
    }
  • Наполните созданную функцию следующим кодом
    Заполнение функции кодом
    // Отключение вкладок
    void CFindSheet::DisablePage(int iFirstPage, ...)
    {
      int iPage = iFirstPage;
      
      va_list marker;
      va_start (marker, iFirstPage);
      int nArgs = 0;
      while(iPage != -1){// Список заканчивается -1
        // Добавить индекс страницы 
        // в массив отключенных страниц, 
        // если его там нет
        int count = (int)m_arrDisabledPages.GetCount();
        bool flag = false;
        for(int i = 0; i < count; i++)
          if(m_arrDisabledPages.GetAt(i) == (UINT)iPage){
            flag = true;
            break;
          }
        if(!flag)
          m_arrDisabledPages.Add(iPage);
      
        SetDisabledText(iPage);  // Наша функция маркирует вкладку
      
        // Получить индекс следующей страницы
        iPage = va_arg(marker, UINT);
        nArgs++; // счетчик вкладок
        ASSERT(nArgs < 100); // Страж зацикливания
      }
    }
Изменение заголовка вкладки

Создадим функцию SetDisabledText(), вызов которой мы предусмотрели в предыдущей функции.

  • Выделите в панели Class View класс CFindSheet и вызовите мастер добавления функций, который заполните так

  • Нажмите кнопку Add, затем кнопку Finish. Мастер добавит заготовку в конец файла FindSheet.cpp, а в описание класса добавит прототип функции
  • Перед заголовком реализации функции добавьте макроопределение, а в тело функции код
    Маркировка вкладок
    
    #define DISABLED_TEXT " - Disabled"
      
    // Маркировка текста заголовков вкладок
    void CFindSheet::SetDisabledText(int iPage)
    {
      CTabCtrl *pTab = GetTabControl();
      ASSERT(pTab);
      TC_ITEM ti;
      char szText[100];
      ti.mask = TCIF_TEXT;
      ti.pszText = szText;
      ti.cchTextMax = 100;
      VERIFY(pTab->GetItem(iPage, &ti));
      strcat(szText, DISABLED_TEXT);
      VERIFY(pTab->SetItem(iPage, &ti));
    }
Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .