Продолжение, начало см. в МК №33-34 (256-257).

ToolBar

Неплохой control для создания панели инструментов входит в состав Microsoft Windows Common Controls 6.0. Он так и называется — Toolbar. Но размер файла mscomctl.ocx — 1 062 704 байт, поэтому предпочтительно создавать toolbar с помощью CommandButton.

Существуют, насколько мне известно, API-функции для создания toolbar, но хорошего я о них сказать ничего не могу, поскольку такой способ создания крайне трудоемок и едва ли себя оправдывает в Visual Basic.

О том, как создать «подставку» для кнопок, будет рассказано в разделе «О рельефных control’ах Delphi». Если вы не в курсе, где VB прячет картинки для toolbar’а, загляните в папку C:\Program Files\Microsoft Visual Studio\Сommon\Graphics\Bitmaps\OffCtlBr\Small\Color. Во всяком случае, в VB 6.0 Enterprise Edition и Professional Edition они лежат именно там. Но вы могли их и не установить: по умолчанию флажок Графика в инсталляторе отключен. Впрочем, графика нужна далеко не вся: почти никогда не используются файлы из папок Video и Cursors. Вообще же, желательно ограбить винт какой-нибудь программой типа Restorator (увы, Restorator не работает под XP) на предмет иконок, картинок и курсоров. Такой запас весит не так уж и много, а нужен регулярно.

Примечание: как это ни удивительно, но у многих начинающих VB-программистов возникают вопросы по поводу размещения картинки на кнопке. Для этого необходимо установить свойство Style=Graphical, Picture=нужная картинка и, если вам нужно, чтобы какой-то цвет был прозрачным, UseMaskColor=True; MaskColor=нужный цвет.

О «драных» формах

Популярным вопросом во многих FAQ является создание «драной» формы, т.е. такой, которая имеет непрямоугольную форму. Технология создания таких форм состоит в объявлении региона с помощью API-функций CreateEllipticRgn, CreatePolygonRgn, CreatePolyPolygonRgn, CreateRectRgn, CreateRoundRectRgn, их комбинированием с помощью API-функции CombineRgn и присвоении этого региона форме. Вот пример, демонстрирующий создание «драной» формы. Если вы запустите его, вы сразу поймете, что я хотел изобразить:

Dim rgn(7) As Long 'Объявляем массив регионов Private Sub Form_Load() Dim p(7) As POINTAPI 'Объявляем массив координат 'Объявляем координаты опорных точек p(1).X = 0: p(1).Y = 0 p(2).X = 20: p(2).Y = 80 p(3).X = 40: p(3).Y = 80 p(4).X = 60: p(4).Y = 0 p(5).X = 50: p(5).Y = 0 p(6).X = 30: p(6).Y = 70 p(7).X = 10: p(7).Y = 0 'Объявляем регионы rgn(0) = CreatePolygonRgn(p(1), 7, 1) rgn(1) = CreateRectRgn(70, 0, 105, 80) rgn(2) = CreateEllipticRgn(80, 0, 130, 45) rgn(3) = CreateEllipticRgn(80, 35, 130, 80) rgn(4) = CreateEllipticRgn(90, 10, 120, 35) rgn(5) = CreateEllipticRgn(90, 40, 120, 70) rgn(6) = CreateRectRgn(80, 10, 105, 35) rgn(7) = CreateRectRgn(80, 40, 105, 70) 'Объединяем четыре первых региона For i = 1 To 3 CombineRgn rgn(0), rgn(0), rgn(i), RGN_OR Next 'Вычитаем четыре последних региона For i = 4 To 7 CombineRgn rgn(0), rgn(0), rgn(i), RGN_DIFF Next SetWindowRgn Me.hWnd, rgn(0), True 'Присваиваем форме регион End Sub 'Удаляем использованные регионы Private Sub Form_Unload(Cancel As Integer) For i = 0 To 7 DeleteObject rgn(i) Next End Sub

Вот что должно появиться (см. Рис. 1).

Рис. 1.

Еще совет: форме желательно иметь свойство BorderStyle=0, т.к. регион отображается и для non-client области, т.е. для заголовка. Очень забавно смотреть на «обрезанную» кнопку закрытия окна. «Драные» формы можно использовать в играх, программах-оболочках для CD, каких-то небольших утилитах, плейерах и crack’ах. Они придают вашему приложению легкую несерьезность, поэтому ни в коем случае не используйте этот совет для создания, скажем, текстового редактора или программы для регулировки высоты кадмиевых стержней в ядерном реакторе!

О рельефных control’ах Delphi

Таких, кажется, два: Panel и Inset, или что-то в этом роде. Их несложно имитировать с помощью Shape и двух Line:

для Panel —Shape c BorderColor = ButtonShadow, как вам угодно по размеру, затем на его верхней и левой стороне Line c BorderColor = ButtonHighlight. Проверьте левую верхнюю точку — она должна принадлежать Line, если нет — исправьте вручную;

для Inset — аналогично, только Line надо размещать на нижней и правой стороне Shape.

Можно написать User Control, который позволит вам особо не утруждать себя слежкой за координатами — он будет делать все сам (если вам в design-time потребуется изменить размер Inset’а или Panel’а, это придется весьма кстати). Весит такая программа в скомпилированном виде 24 Кб (сравните с Delphi!), в OCX’ах эти control’ы весят оба по те же 24 Кб, но это не учитывая самой программы. Какой же из этого надо сделать вывод? Создайте свою библиотеку нужных вам пользовательских управлений CTL, а затем по мере надобности добавляйте их в свой проект. Вообще же, даже новичкам-программистам следует уже сейчас начинать создавать свою библиотеку компонентов, функций и методов. Опыт показывает: серьезные программисты пишут только 10% программы, остальные 90% были уже написаны ими ранее. Действительно, в каждой программе встречаются стандартные задачи, а повторение не всегда мать учения. В данном случае разумно руководствоваться принципом «трудолюбивой лени» — сделать один раз, чтобы потом не делать ни разу.

О разделителях в меню

Как это ни удивительно, но среди писем начинающих KVB’шников (Крутых VB’шников?) частенько попадаются вопросы, как добавить разделитель в меню. Загляните в любое меню «Файл» и почти наверняка вы увидите перед «Выходом» такой разделитель. Создать его совсем не сложно — достаточно в редакторе меню в свойстве Caption прописать символ -.

(Продолжение следует)