Політ: книга програмера  
0. Вступ
1. Особливості політівських програм
2. Події та їх обробники
3. Елементи керування: принципи, Button, Label, Check, Radio,
InpLine, PicCtl, Header, Progress, Track, TimerCtl, Notebook,
SpinEdit, PopupBtn, Switcher, MainMenu, Splitter, Memo, ListBox

Сайт Польоту
 

Елементи керування
Кнопка-меню - PopupBtn (Модуль Ctl)

Кнопка-меню, як неважко здогадатись, це модифікація звичайної кнопки Button. Точніше, це елемент керування, побудований на основі Button. PopupBtn відрізняється тим, що за умовчанням має мітку bmMenuDown та при натисненні відкриває указане меню. Про роботу з меню я вам ще не розповідав; тому в тестовій програмці я вам наведу маленький приклад створення меню, а детальніше ми розглянемо політівські меню потім.

Кнопки-меню використовуються в політівських програмах дуже широко, особливо в панелях настройки, і особливо в настройках екрана :).




Створити кнопку-меню
Function PopupBtn_Create(Prog:PProg; VCaption:String; 
  VMenu:PMenuItem; VPicture:Pointer; 
  VPicturePos:TPicturePos): PControl;
  • VCaption - напис на кнопці.
  • VMenu - вказівник на меню, яке буде відкриватися при натисканні кнопки.
  • VPicture - картинка на кнопці; Nil - без картинки.
  • VPicturePos - положення картинки на кнопці (ppleft - зліва від напису, ppTop - над написом). Якщо картинки нема, використовуйте ppLeft.


Намалювати кнопку-меню
Procedure PopupBtn_Paint(Me:PControl; 
  VX1,VY1,VX2:Integer);
VX1, VY1, VX2 - координати кнопки. Висота при PicturePos=ppLeft дорівнює 20 пікселів, при ppTop - 35 пікселів.



Розглядати кнопку-меню як кнопку (Button)
Function PopupBtn_AsButton(Me:PControl): PControl;
Технічно функція повертає вказівник на кнопку (Button), яка використовується цією кнопкою-меню (PopupBtn). Це зроблено для того, щоб мати доступ до всіх процедур роботи з кнопкою (змінити підпис, картинку, мітку, стан натисненості...), не дублюючи їх у PopupBtn. У тестовій програмці я покажу, як користуватись цим.



А ось, власне, і тестова програмка :). Робимо заготовку TestPbt (з обробниками за умовчанням), доаємо в її Uses модуль Popup. Оголошуємо змінні:
PbtTest: PControl;
MnuIcons: PMenuItem;
Створюємо меню, а потім кнопку-меню:
MnuIcons:=Popup.CreateMenu;
Popup.AddCommand(MnuIcons, 'Галочка', '', 
  'Kernel.PicOK', Kernel.PicOK, True, OnIconsMenuClick);
Popup.AddCommand(MnuIcons, 'Хрестик', '', 'Kernel.PicClose', 
  Kernel.PicClose, True, OnIconsMenuClick);
Popup.AddCommand(MnuIcons, 'Кружечок', '', 'Kernel.PicApply', 
  Kernel.PicApply, True, OnIconsMenuClick);
PbtTest:=Ctl.PopupBtn_Create(Me, 'Меню', MnuIcons, 
  Nil, ppLeft);
Пропоную звернути увагу на те, як створюється меню. Це робиться перед його використанням (тобто перед створенням кнопки-меню). Спочатку для змінної меню (фактично, вказівник на тип TMenuItem, описаний у модулі Types) викликаємо Popup.CreateMenu (створити порожнє меню). Потім у меню по одній додаються команди процедурою Popup.AddCommand. Її формат такий:
Procedure AddCommand(Var VMenu:PMenuItem; 
  VName,VHotKey,VHint:String;
  VIcon:Pointer; VEnabled:Boolean; VOnClick:TMenuProc);
  • VName - текст елемента меню.
  • VHotKey - гаряча клавіша елемента меню.
  • VHint - хінт елемента меню (текст, що показується при затримці мишки над елементом меню).
  • VIcon - іконка елемента меню (як і завжди, Nil - значить без іконки).
  • VEnabled - флажок доступності елемента меню (True - доступний, False - недоступний). Недоступний елемент малюється іншим кольором (сірим) і не може бути вибраним з меню.
  • VOnClick - обробник кліку на елементі меню. Формат процедури-обробника такий:
    TMenuProc=Procedure(Me:PProg; Item:PMenuItem);
    Тут Me - програма, Item - вказівник на клікнутий елемент меню.
Зараз ми якраз і займемося цим обробником:
Procedure OnIconsMenuClick(Me:PProg; Item:PMenuItem);
Var
  TempBtn: PControl;
Begin
  With Me^, TTestPbtData(Me^) Do
  Begin
    TempBtn:=Ctl.PopupBtn_AsButton(PbtTest);
    Ctl.Button_SetPicture(TempBtn, Item^.Icon)
  End
End;
А тут зверніть увагу ось на що. Технічно наша PbtTest не є кнопкою Button. Це інший елемент керування - PopupBtn. Не існує, скажімо, метода PopupBtn_SetPicture. Замість цього треба робити так: спочатку функцією PopupBtn_AsButton треба отримати вказівник на справжню кнопку (Button), якою так би мовити володіє PopupBtn. Із цим вказівником уже можна працювати як із звичайним Button'ом, зокрема писати Button_SetPicture(TempBtn...). Заради науки все ж можете написати в цьому обробнику прямо:
Ctl.Button_SetPicture(PbtTest, Item^.Icon);
Вам потрібні такі глюки? Тоді ще раз прочитайте попередній абзац та запам'ятайте на все життя: якщо змінна створена як PopupBtn, то далі з нею можна працювати лише процедурами, що починаються на PopupBtn_. Це стосується і всіх інших політівських елементів керування. Ніякої автоматичної перевірки тут нема (принаймні поки що); вам доведеться слідкувати за цим самостійно. А кому зараз легко? :)