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

Однодокументный интерфейс MFC

Создание комбинированного списка на панели инструментов

Прежде всего создадим идентификатор ID, который далее при создании списка программно система свяжет с самим списком и далее под этим ID будет учитывать этот список во всех других функциях управления списком.

  • Выберите вкладку Resource View и через контекстное меню выполните опцию Resource Symbols (Символы ресурсов). Появится окно

  • Нажмите кнопку New..., появится окно New Symbol, в котором в поле Name введите идентификатор IDC_CBWIDTH, а поле Value оставьте по умолчанию

Для программной поддержки комбинированного списка создадим переменную m_ctrlWidth типа CComboBox как член класса CMainFrame. Для этого:

  • Во вкладке Clas View выделите класс CMainFrame и через контекстное меню вызовите мастер Add Variable, который заполните так

  • Убедитесь в том, что мастер добавил переменную именно в класс CMainFrame файла MainFrm.h

Далее нам нужно будет выполнить такие действия:

  1. Установить ширину и идентификатор ID заглушки-заполнителя комбинированного списка на панели инструментов равными соответственно ширине и идентификатору ID самого комбинированного списка
  2. Определить размер и позицию комбинированного списка, получив для этого параметры заглушки-заполнителя на панели инструментов
  3. Создать комбинированный список как программный объект, указав при этом панель инструментов в качестве его родительского окна
  4. Загрузить текстовые строки в комбинированный список и установить индекс видимой начальной строки

Чтобы упорядочить этот процесс и не захламлять функцию OnCreate() класса фреймового окна CMainFrame не свойственным ей кодом, создадим отдельную функцию-член фрейма, а в функции OnCreate() разместим вызов этой вспомогательной упаковки кода. Вспомогательную функцию назовем CreateColorBar().

  • Выделите во вкладке Class View класс CMainFrame
  • Вызовите мастер Add Function, который заполните так

  • Перенесите (это значит полностью уберите со старого места!!!) соответствующий код из функции OnCreate() файла MainFrm.cpp в эту новую функцию (файл тот же!), а также добавьте новый код для создания комбинированного списка

Ниже приведен листинг функции, где красным выделен перенесенный код, а синим - добавленный новый код

Вспомогательная функция в файле MainFrm.cpp
// Вспомогательная упаковка кода создания панели инструментов
bool CMainFrame::CreateColorBar(void)
{
  // Создать инструментальную панель 
  // для выбора цвета и настроить ее
  if (!m_wndColorBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
    | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    !m_wndColorBar.LoadToolBar(IDR_TBCOLOR))
  {
    TRACE0("Failed to create toolbar\n");
    return FALSE;      // fail to create
  }
  // Найти кнопку ID_COLOR_BLACK на инструментальной панели
    int iTBCtrlID = m_wndColorBar.CommandToIndex(ID_COLOR_BLACK);
  if(iTBCtrlID >= 0){
    // Установить все кнопки так, чтобы
    // они действовали как радиокнопки в группе
    for(int i = iTBCtrlID; i < (iTBCtrlID + 8); i++)
      m_wndColorBar.SetButtonStyle(i, TBBS_CHECKGROUP);
  }
  
  // Добавить комбинированный список
  int nWidth = 100;
  int nHeight = 125;
  
  // Выбрать конфигурацию заглушки-заполнителя комбинированного списка
  m_wndColorBar.SetButtonInfo(9, IDC_CBWIDTH, TBBS_SEPARATOR, nWidth);
  
  // Получить высоту панели инструментов выбора цвета
  CRect rect;
  m_wndColorBar.GetItemRect(9, &rect);
  rect.bottom = rect.top + nHeight;
  
  // Создать комбинированный список
  m_ctrlWidth.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST
                      ,rect, &m_wndColorBar, IDC_CBWIDTH);
  
  // Заполнить комбинированный список текстами из ресурса String Table
  CString str;
  UINT id = IDS_WIDTH_1; // Важно, что значения идентификаторов
                           // расположены в порядке возрастания с шагом 1,
                         // поэтому можно организовать цикл
  for(; id - IDS_WIDTH_1 < 11; id++) // Перебираем 11 элементов
    if(str.LoadString(id))
      m_ctrlWidth.AddString((LPCTSTR)str);
  
  // Устанавливаем первый элемент видимым
  m_ctrlWidth.SetCurSel(0);
  
  return TRUE;
}

В приведенном коде используется функция

// Выбрать конфигурацию заглушки-заполнителя комбинированного списка
  m_wndColorBar.SetButtonInfo(9, IDC_CBWIDTH, TBBS_SEPARATOR, nWidth);

Первый параметр (9) - означает индекс размещаемого в панели элемента ( начинается с нуля ). Этим модифицируемым элементом-заглушкой будет ранее введенный нами последний сепаратор в файле ресурсов. Фрагмент файла ресурсов таков

Идентификаторы элементов строки состояния в файле ресурсов
/////////////////////////////////////////////////////////////////////////////
//
// Toolbar
//

IDR_TBCOLOR TOOLBAR  16, 15
BEGIN
    BUTTON      ID_COLOR_BLACK
    BUTTON      ID_COLOR_BLUE
    BUTTON      ID_COLOR_GREEN
    BUTTON      ID_COLOR_CYAN
    BUTTON      ID_COLOR_RED
    BUTTON      ID_COLOR_MAGENTA
    BUTTON      ID_COLOR_YELLOW
    BUTTON      ID_COLOR_WHITE
    SEPARATOR
    SEPARATOR  // заглушка-заполнитель как элемент с индексом 9
END

Второй параметр - идентификатор ресурса комбинированного списка, для которого резервируется место на панели и за которым в дальнейшем функция Create() закрепит комбинированный список как приемник сообщений.

Третий параметр - стандартная константа TBBS_SEPARATOR библиотеки MFC, представляющая разделитель панели инструментов.

Четвертый аргумент - ширина заглушки-заполнителя для резервируемого места под комбинированный список.

  • Вновь дополните функцию CMainFrame::OnCreate() кодом вызова только что созданной упаковки CMainFrame::CreateColorBar(), после чего функция должна выглядеть так
    Вызов вспомогательной функции из OnCreate()
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
      if (CFrameWnd::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(!CreateColorBar()){
        TRACE0("Failed to create color toolbar\n");
        return -1;
      }
      
      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
      }
      
      m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
      m_wndColorBar.EnableDocking(CBRS_ALIGN_ANY);// Наша!!!
      EnableDocking(CBRS_ALIGN_ANY);
      
      DockControlBar(&m_wndToolBar);
      DockControlBar(&m_wndColorBar);// Наша!!!
      
      return 0;
    }
  • Постройте приложение и убедитесь, что список раскрывается, но ничего пока не делает

Мы создали комбинированный список как немодальное окно с помощью функции Create, которая выглядит так

Функция Create в файле MainFrm.cpp
// Вспомогательная упаковка кода создания панели инструментов
bool CMainFrame::CreateColorBar(void)
{
...............................................................
  // Создать комбинированный список
  m_ctrlWidth.Create(WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST
                      ,rect, &m_wndColorBar, IDC_CBWIDTH);
.......................................................................
  return TRUE;
}

Первым аргументом этой функции является сочетание стилей комбинированного списка, определяющих его внешние свойства и поведение. Часть флажков относятся к оконным стилям WS_ (window style) , поскольку комбинированный список наследует класс CWnd, а часть флажков специфицирует стиль только списка ( CBS_ - ComboBox Style ). Перечислим значения флажков стилей списка

Стили комбинированного списка
Стиль Описание
WS_CHILD Указывает, что данное окно является дочерним (обязательный стиль)
WS_VISIBLE Делает комбинированный список изначально видимым
WS_DISABLED Отключает комбинированный список
WS_VSCROLL Добавляет вертикальную прокрутку к раскрывающемуся списку
WS_HSCROLL Добавляет горизонтальную прокрутку к раскрывающемуся списку
WS_GROUP Группирует элементы управления
WS_TABSTOP Включает комбинированный список в последовательность перехода по клавише Tab
CBS_AUTOHSCROLL Обеспечивает прокрутку текста в поле редактирования при его заполнении
CBS_DROPDOWN Подобен стилю CBS_SIMPLE, но не отображает список до тех пор, пока пользователь не выберет пиктограмму, следующую за полем редактирования
CBS_DROPDOWNLIST Подобен стилю CBS_DROPDOWN. Однако заменяет поле редактирования статическим текстом, который отображает текущее выбранное значение элемента списка
CBS_HASSTRINGS Указывает, что за перерисовку комбинированного списка отвечает владелец. Элементы в окне списка состоят из строк
CBS_OEMCONVERT Текст, выводимый для отображения на экране в поле редактирования, конвертируется из набора символов ASCII в набор OEM, а затем, при передаче данных из комбинированного списка в программу - опять из набора OEM в набор символов ASCII. Набор отображаемых символов ASCII используется в MS-DOS, а OEM - в Windows. Символы с кодами 32-127 обычно совпадают в обеих системах. Другие же символы, используемые национальными кодировками, требуют конвертации. Для правильного отображения текста на экране в консольном режиме для этого используется функция CharToOem(char* strASCII, char* strOEM)
CBS_OWNERDRAWFIXED Указывает, что владелец списка отвечает за перерисовку содержимого. Содержимое списка имеет фиксированную высоту
CBS_OWNERDRAWVARIABLE Указывает, что владелец списка отвечает за перерисовку содержимого. Высота содержимого списка может изменяться
CBS_SIMPLE Все время отображает список на экране
CBS_SORT Автоматически сортирует строки в списке
CBS_DISABLENOSCROLL Если список не содержит достаточно элементов для прокрутки, все равно отображается полоса прокрутки, хоть и в отключенном ( Disabled ) виде
CBS_NOINTEGRALHEIGHT Указывает, что комбинированный список имеет точно указанный размер
Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .