|
||||
|
Программирование на Visual C++Выпуск №19 от 15 октября 2000 г. Приветствую всех! WinAPI & MFC Тонкая настройка панели инструментов Задание внешнего вида кнопок и размещение отличных от кнопок элементовПанель инструментов (Toolbar) cейчас является, пожалуй, одной из обязательных частей любого профессионально сделанного приложения. И тем более становится обидно, что используя стандартные заготовки, ничего, кроме маленьких кнопочек поместить на эту панель нельзя. Но что делать, если внешний вид приложений MS Office или VC IDE не дает вам спокойно спать? Если вам просто необходимо идти в ногу с конкурирующими программами, где с этим как раз все в порядке? Если вы решили, что размещение дополнительных элементов управления на панели инструментов сразу сделает интерфейс гораздо понятнее и удобнее ?.. Тогда нужно просто взять и сделать это. Да, для этого придется приложить некоторые усилия. Так что любители "рисовать приложения" могут спокойно об этом забыть, а еще лучше – перейти на C++Builder или Delphi, где их способности к рисованию смогут реализоваться в полной мере. (Ладно, не обижайтесь.) Самое большое преимущество Visual C++ в том, что при желании с его помощью можно сделать практически ВСЕ, ЧТО УГОДНО. Главное, знать как. Не пугайтесь – от вас потребуется совсем немного. Но для начала давайте выясним, можно ли просто изменить стандартный вид тулбара (так для краткости я буду именовать панель инструментов). Например, сделать тулбар а'ля WinZip – большие иконки, с подписями… Итак, какие настройки нам доступны практически сразу же? – Конечно же, стили. Оперируя стилями, мы тоже можем повлиять на внешний вид панели. Вот самые интересные из них: CCS_TOP и CCS_BOTTOM — задают размещение тулбара — вверху или внизу окна. (CСS_TOP используется по умолчанию.) TBSTYLE_FLAT — Делает кнопки плоскими. (Используется по умолчанию.) TBSTYLE_LIST — Используется для вывода текста справа от кнопки. (Помните пункт "выборочно текст справа" в IE4 и Outlook?) Остальные стили вы можете, в принципе, посмотреть сами – они задают некоторые другие параметры. Но нам сейчас нужно другое: сделать кнопки большими и с подписями. Выполнить это можно с помощью членов классов CToolBar и CToolBarCtrl, а если вы работаете не в MFC, то придется работать с сообщениями. Вышеупомянутые классы MFC располагают богатым набором функций для всевозможной настройки тулбара. Функции CToolBarCtrl::SetButtonSize(), CToolBarCtrl::SetBitmapSize(), CToolBarCtrl::SetButtonWidth(), CToolBar::SetButtonText(), CToolBar::SetHeight() говорят сами за себя. Именно они понадобятся нам для реализации такого тулбара, как в WinZip. Без MFC это можно сделать, послав тулбару сообщения _SETBUTTONSIZE, TB_SETBITMAPSIZE, TB_SETBUTTONWIDTH, TB_ADDSTRING и др. Кстати, многие функции классов MFC делают фактически то же самое – просто посылают соответствующие сообщения. Можете сами поиграться с различными настройками. Если бы я взялся здесь подробно описывать ВСЕ возможности, и как каждую реализовать, то эта статья растянулась бы минимум на дюжину выпусков. Цель данной публикации – дать вам общее представление, направление, так сказать. Я не думаю, что обязательно нужно все разжевывать и, как это часто происходит, сводить мысль к "нажмите туда, выберите то". Я хочу, чтобы вы учились думать сами. Психологи приводят следующую статистику: когда человек просто прочитывает информацию, то запоминает не более 50% из прочитанного. Если еще и записывает – не более 70%. Но если человеку информация досталась с некоторым трудом, если он ее нашел сам – то запоминается более 90%! Сделайте выводы. Теперь пришла пора перейти к самому интересному вопросу, который я рассмотрю гораздо подробнее, а именно – как на тулбаре разместить что-либо, не являющееся кнопкой. Я буду рассказывать как это делается в MFC, хотя понять, как это сделать в API после ознакомления с текстом не составит никакого труда. Как обычно, если мы хотим заставить что-то стандартное работать нестандартно, нужно создавать класс-наследник. В нашем случае это будет наследник CToolBar, обозначим его CAdvBar. В нем вы сможете обрабатывать все события, поступающие от контролов, размещенных на тулбаре. А теперь самая суть: как именно можно что-то поместить на тулбар. Дело в том, что существует возможность программно управлять шириной элементов-сепараторов. Таким образом, сепараторы становятся как бы "местами содержания" наших контролов. В редакторе ресурсов отведите отдельную кнопку на тулбаре – в будущем вместо нее появится ваш элемент управления. Теперь для удобства определим следующие символические константы: CONTROL_INDEX — порядковый номер кнопки-содержателя контрола; CONTROL_WIDTH — ширина контрола; CONTROL_HEIGHT — высота контрола. Включите контрол в качестве члена в класс CAdvBar. Еще нужно создать функцию инициализации, которая будет подменять кнопку нашим контролом (конструктор или обработчик OnCreate в данном случае не подходят, т.к. вызываются слишком рано). Пускай, например, нам нужно поместить на тулбар элемент управления типа ComboBox. Тогда: class CAdvBar : public CToolBar { … protected : CComboBox m_ComboBox; // наш контрол void Initialize( ); // ф-ция инициализации … } Функция инициализации превращает нашу кнопку в сепаратор и устанавливает ему нужную ширину, после чего создает и позиционирует контрол на его место. Пример для комбобокса: void CAdvBar::Initialize() { CRect rc; SetHeight(CONTROL_HEIGHT + 8); // устанавливаем нужную толщину тулбара // превращаем кнопку в сепаратор нужных размеров // (IDC_COMBO - ID кнопки) SetButtonInfo(CONTROL_INDEX, IDC_COMBO, TBBS_SEPARATOR, CONTROL_WIDTH); GetItemRect (CONTROL_INDEX, rc); // получаем координаты сепаратора // теперь создаем комбобокс. // не забывайте, что для этого контрола при создании указывается // его высота В РАЗВЕРНУТОМ ВИДЕ, именно поэтому // мы к ней прибавляем еще 100 пикселов. rc.bottom += 100; m_ComboBox.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_AUTOHSCROLL | CBS_DROPDOWN, rc, this, IDC_COMBO); // настраиваем контрол m_ComboBox.AddString("Строка 1"); m_ComboBox.AddString("Строка 2"); m_ComboBox.SetCurSel(0); } В данном случае еще могу порекомендовать в комбобоксе изменить шрифт на пропорциональный. Вот, теперь все, что осталось сделать – в CMainFrame::OnCreate() после создания тулбара вызвать Initialize(). Взаимодейстиве с контролом, размещенным на тулбаре, происходит через соответствующий член класса и/или посредством сообщений. ВОПРОС-ОТВЕТИз ответов, содержащих одинаковое решение, я выбрал лучшие (с моей точки зрения). Большая просьба: не нужно присылать мне целые проекты и большие куски кода. Лучше объясните ваше решение словами.
К сведению: Не во всех системах есть такие ключи реестра. В Windows NT/2000, например, их нет. Хочу поблагодарить всех, кто откликнулся и прислал ответ на вопрос. Если хотите чтобы ваш ответ был опубликован – постарайтесь, чтобы он был лучше других! Напоминаю, что только вопросы от авторов опубликованных ответов и материалов имеют в дальнейшем приоритет. (Вопросы, естественно, должны быть по программированию). В ПОИСКАХ ИСТИНЫ
Начинающим программистам рекомендую подписаться на дружественную рассылку: Практикум программирования на C++ под Windows Учебный курс по программированию на языке C++ под Windows. Предназначена для тех, кто уже (немного) умеет программировать, но не знает языка C++ или идеологии написания программ под Windows. В планах — изучение Win32 API, MFC, терминологии Windows и технологий, связанных с ней. Ответы на вопросы, глоссарий, приложения. Будьте здоровы! (Алекс Jenter jenter@mail.ru) (Красноярск, 2000.) |
|
||
Главная | В избранное | Наш E-MAIL | Прислать материал | Нашёл ошибку | Наверх |
||||
|