Читайте также: |
|
Тема: Стандартні технологій програмування. Інтерфейси Drag-and-Drop і Drag-and-Dock. Управління мишкою. Передача фокусу вводу між елементами управління. Створення і використання ярликів.
План:
1. Інтерфейс перенесення і прийому компонентів
4. Управління мишею
5. Ярлики
Інтерфейс перенесення і прийому компонентів забезпечує взаємодію двох елементів управління під час виконання приложення.
Для того, щоб механізм запрацював, потрібно набудувати відповідним чином два елементи управління. Один повинен бути джерелом (Source), другий — приймачем (Target). При цьому джерело нікуди не переміщається, а тільки реєструється як таке в механізмі.
Один елемент управління може бути одночасне джерелом і приймачем.
Користувач поміщає покажчик миші на потрібний елемент управління, натискає ліву кнопку миші і, не відпускаючи її, починає переміщати курсор до другого елементу. Досягши цього елементу користувач відпускає кнопку миші. У цей момент виконуються передбачені розробником дії. При цьому перший елемент управління є джерелом, а другий — приймачем.
Після виконання настройки механізм включається і реагує на перетягання мишею компоненту-джерела в приймач. Група методів-обробників забезпечує контроль всього процесу і служить для зберігання початкового коду, який розробник визнає потрібним пов'язати з перетяганням. Це може бути передача тексту, значень властивостей (з одного редактора в іншій можна передати настройки інтерфейсу, шрифту і сам текст); перенесення файлів і зображень; просте переміщення елементу управління з місця на місце і так далі Приклад реалізації Drag-and-Drop в Windows — можливість перенесення файлів і папок між дисками і папками.
Весь механізм Drag-and-Drop реалізований в базовому класі TControl, який є предком всіх елементів управління. Розглянемо суть механізму.
Будь-який елемент управління з Палітри компонентів Delphi є джерелом в механізмі Drag-and-Drop. Його поведінка на початковому етапі перенесення залежить від значення властивості:
type TDragMode = (dmManual, dmAutomatic); property DragMode: TDragMode;
Значення dmAutomatic забезпечує автоматичну реакцію компоненту на натиснення лівої кнопки миші і початок перетягання — при цьому механізм включається самостійно.
Значення dmManual (встановлено за умовчанням) вимагає від розробника забезпечити включення механізму уручну. Цей режим використовується в тому випадку, якщо компонент повинен реагувати на натиснення лівої кнопки миші якось інакше. Для ініціалізації перенесення використовується метод:
procedure BeginDrag(Immediate: Boolean; Threshold: Integer = -1);
Параметр immediate = True забезпечує негайний старт механізму. При значенні False механізм включається тільки при переміщенні курсора на відстань, визначену параметром Threshold.
Про включення механізму сигналізує покажчик миші — він змінюється на курсор, визначений у властивості
property DragCursor: TCursor;
Ще раз нагадаємо, що джерело при переміщенні курсора не змінює власного положення, і лише у разі успішного завершення перенесення зможе взаємодіяти з приймачем.
Приймачем може стати будь-який компонент, в якому створений метод-обробник
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
Він викликається при переміщенні курсора в режимі Drag-and-Drop над цим компонентом. У методі-обробнику можна передбачити вибір джерел перенесення по потрібних атрибутах.
Якщо параметр Accept отримує значення True, то даний компонент стає приймачем. Джерело перенесення визначається параметром source. Через цей параметр розробник дістає доступ до властивостей і методів джерела. Поточне положення курсора задають параметри X і Y. Параметр state повертає інформацію про характер руху миші:
type TDragState = (dsDragEnter, dsDragLeave, dsDragMove);
dsDragEnter — покажчик з'явився над компонентом; dsDragLeave — покажчик покинув компонент; dsDragMove — покажчик переміщається по компоненту.
Приймач повинен передбачати виконання деяких дій у випадку, якщо джерело завершить перенесення саме на нім. Для цього використовується метод-обробник
type TDragDropEvent = procedure (Sender, Source: TObject; X, Y: Integer) ofobject;
property OnDragDrop: TDragDropEvent;
який викликається при відпуску лівої кнопки миші на компоненті-приймачі. Доступ до джерела і приймача забезпечують параметри Source і Sender відповідно. Координати миші повертають параметри X і Y.
При завершенні перенесення елемент управління — джерело — отримує відповідне повідомлення, яке обробляється методом
type TEndDragEvent = procedure (Sender, Target: TObject; X, Y: Integer) of object; property OnEndDrag: TEndDragEvent;
Джерело і приймач визначаються параметрами Sender і Target відповідно. Координати миші визначаються параметрами X і Y.
Для програмної зупинки перенесення можна використовувати метод EndDrag джерела (при звичайному завершенні операції користувачем він не використовується):
procedure EndDrag(Drop: Boolean);
Параметр Drop = True завершує перенесення. Значення False перериває перенесення.
Інтерфейс приєднання Drag-and-Dock
Ряд елементів управління (а конкретно — нащадки класу xwinControl) можуть служити носіями (доками) для інших елементів управління з можливістю їх динамічного переміщення з одного дока в іншій за допомогою миші. Перетягувати можна практично все — від статичного тексту до форм включно. Приклад використання техніки Drag-and-Dock дає саме середовище розробки Delphi — з її допомогою можна об'єднувати на екрані різні інструменти, такі як Інспектор об'єктів і Менеджер проекту.
Як і у випадку з технологією перетягання Drag-and-Drop, можливі два варіанти реалізації техніки Drag-and-Dock: автоматичний і ручний. У першому випадку справа зводиться до установки потрібних значень для декількох властивостей, а решту частини роботи бере на себе код VCL; у другому, як випливає з назви, вся робота покладається на програміста.
Отже, що ж потрібно зробити для впровадження Drag-and-Dock? У Інспекторові об'єктів необхідно змінити значення властивості DragKind на dkDock, а властивості DragMode — на dmAutomatic. Тепер цей елемент управління можна перетягувати з одного носія-дока на іншій.
Носієм інших компонентів (доком) може служити нащадок TWinControl. У нього є властивість Docksite, установка якої в True вирішує перенесення на нього інших компонентів. Якщо при цьому ще і встановити властивість AutoSize в True, док автоматично масштабуватиметься залежно від того, що на нім знаходиться. В принципі, цими трьома операціями вичерпується мінімальний обов'язковий набір.
Природно, для програміста передбачені можливості контролю за цим процесом. Кожен переносимий елемент управління має дві події, що виникають в моменти початка і кінця перенесення:
type TStartDockEvent = procedure (Sender: TObject; var DragObject: TDragDockObject) ofobject ;TEndDragEvent = procedure (Sender, Target: TObject; X, Y: Integer) ofobject;У першому з методів sender — це переносимий об'єкт, а DragObject — спеціальний об'єкт, що створюється на час процесу перенесення і містить його властивості. У другому sender — це також переносимий об'єкт, а Target — об'єкт-док.
Док теж сповіщається про події під час перенесення:
type TGetSitelnfoEvent = procedure (Sender: TObject; DockClient: TControl; var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean) ofobject ; TDockOverEvent = procedure (Sender: TObject; Source: TDragDockObject; X, Y: Integer; State: TDragState; var Accept: Boolean) ofobject ; TDockDropEvent = procedure (Sender: TObject; Source: TDragDockObject; X, Y: Integer) ofobject ; TUnDockEvent = procedure (Sender: TObject; Client: TControl; NewTarget: TWinControl; var Allow: Boolean) ofobject;Як тільки користувач натиснув кнопку миші над переносимим компонентом і почав зрушувати його з місця, всім потенційним докам (компонентам, властивість яких Docksite встановлена в True) розсилається подія onGetsiteinfo. З ним передаються параметри: хто хоче "приземлитися" (параметр Dockclient) і де (MousePos). У відповідь док повинен повідомити рішення, приймає він компонент (параметр CanDock) і прямокутник, що надається, чи ні. За допомогою цієї події можна приймати тільки певні елементи управління, як показано в прикладі:
procedure TForml.PanellGetSitelnfо(Sender: TObject; DockClient: TControl; var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean); begin if DockClient is TBitBtn then CanDock:= False; end;Два подальших події в точності відповідають своїм аналогам з механізму перенесення Drag-and-Drop). Подія onDockOver відбувається при переміщенні перетягуваного компоненту над доком, OnDockDrop — у момент його відпуску. Нарешті, onUnDock сигналізує про відхід компоненту з дока і відбувається у момент його "приземлення" у іншому місці.
Між доком і елементами, що містяться на нім, управління є двосторонній зв'язок. Всі "припарковані" елементи управління містяться у векторній властивості Dockclients, а їх кількість можна дізнатися з властивості
DockClientCount:s: = ' '; for i:= 0 to Panell.DockClientCount - 1 do AppendStr(s, Panell.DockClients[i].Name + #0$D#0$A);ShowMessage(s);З іншого боку, якщо елемент управління знаходиться на доці, то посилання на док розташовується у властивості HostDocksite. З її допомогою можна встановити, де знаходиться елемент, і навіть поміняти властивості дока:
procedure TMyForm.Button1EndDock(Sender, Target: TObject; X, Y: Integer); begin (Sender as TControl).HostDockSite.SetTextBuf(pChar((Sender as TControl).Name)); end;Компоненти можна не тільки переносити з одного дока на іншій, але і відпускати в будь-якому місці. Хоча сам по собі компонент TControl і його нащадки не є вікнами Windows, але спеціально для цього випадку створюється вікно-носій. Властивість FloatingDockSiteClass якраз і визначає клас створюваного вікна. За умовчанням для більшості компонентів значення цієї властивості рівне TCustomDockForm. Це — форма, яка володіє властивостями дока і створюється у момент відпуску елементу управління поза іншими доками. Зовні вона нічим не відрізняється від звичайної стандартної форми. Якщо ви хочете, щоб ваша плаваюча панель інструментів виглядала по- особливому, потрібно породити нащадка від класу TCustomDockForm 1пов'язати властивість FloatingDockSiteClass з цим породженим класом:
TMyCustomFloatingForm = class (TCustomDockForm) public constructor Create(AOwner: TComponent); override; end; constructor TMyCustomFloatingForm.Create(AOwner: TComponent}; begin inherited Create(AOwner); BorderStyle:= bsNone; end; procedure TForml.FormCreate(Sender: TObject); begin ToolBarl.FioatingDockSiteCiass:= TMyCustomFloatingForm; end;В даному прикладі вирішено типове завдання — зробити так, щоб вікно плаваючої панелі інструментів, що несе, не містило заголовка.
Переносити компоненти можна не тільки за допомогою миші, але і програмно. Для цього є пара методів ManualDock і ManualFioat. У прикладі, що наводиться нижче, натиснення кнопки з ім'ям BitBtnl переносить форму custForm на док MainForm.Paneil і розміщує її за всією доступною площею (параметр вирівнювання alclient). Натиснення кнопки BitBtn2 знімає цю форму з дока і вирівнює її по центру екрану. У властивостях UndockHeight і UndockWidth зберігаються висота і ширина елементу управління на момент, передуючий приміщенню на док:
procedure TMainForm.BitBtn1Click(Sender: TObject); begin GustForm.ManualDock(MainForm.Panel1, nil, alClient); end; procedure TMainForm.BitBtn2Click(Sender: TObject); begin with CustForm do begin ManualFloat(Rect((Screen.Width - UndockWidth) div 2 (Screen.Height - UndockHeight) div 2, (Screen.Width + UndockWidth) div 2 (Screen.Height + UndockHeight) div 2)); end; end; Управління фокусом
В процесі роботи приложення той або інший елемент управління отримує фокус введення залежно від дій користувача. Дуже часто передача фокусу між елементами управління повинна бути впорядкована. Наприклад, при введенні даних в приложеннях баз даних користувач повинен мати максимум зручностей для забезпечення хорошої продуктивності праці. Для цього він повинен працювати тільки з клавіатурою, не відволікаючись на зайві операції по передачі фокусу в потрібний компонент за допомогою миші.
Для вирішення подібного роду проблем всі віконні елементи управління мають дві властивості. Властивість TabOrder визначає порядок передачі фокусу між елементами управління одного власника (форми, панелі, групи) при натисненні клавіші <Таb>. Значення 0 має компонент, який отримуватиме фокус при відкритті форми.
Для того, щоб властивість TabOrder працювала, властивість Tabstop повинна мати значення True.
Окрім цього, всі кнопки (події від TButtonControl) мають властивість Default, яка при значенні True примушує кнопку реагувати на натиснення клавіші <Enter> як на клацання на кнопці, навіть якщо вона не має фокусу. Тільки одна кнопка на формі може мати цю властивість встановленим.
Для передачі фокусу будь-якому віконному елементу управління програмними засобами можна використовувати метод
procedure SetFocus; virtual;
успадкований від класу TWinControl.
При необхідності роботи у формі застосовується метод
function SetFocusedControl(Control: TWinControl): Boolean; virtual;
класу TForm, в параметрі указується покажчик на компонент, що належить формі.
Управління мишею
Кожен елемент управління володіє набором властивостей і методів, що забезпечують управління мишею. Зрозуміло, що це важливий і потрібний механізм. Розглянемо стисло його пристрій.
Дія мишею на інтерфейсні елементи приложення розробник може відстежувати за допомогою цілої групи методів-обробників.
На натиснення кнопки миші реагує метод
type
TMouseEvent = procedure (Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer) of object;
property OnMouseDown: TMouseEvent;
У параметрі Button передається ознака натиснутої кнопки:
type TMouseButton = (mbLeft, mbRight, mbMiddle);
Параметр shift визначає натиснення додаткової клавіші на клавіатурі:
type TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble);
Параметри х і у повертають координати курсора.
На відпуск кнопки миші реагує метод:
type
TMouseEvent = procedure (Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer) of object;
property OnMouseUp: TMouseEvent;
Його параметри описані вищe.
При переміщенні миші можна викликати метод-обробник
TMouseMoveEvent = procedure(Sender: TObject;
Shift: TShiftState; X, Y: Integer) of object;
property OnMouseMove: TMouseMoveEvent;
Якщо у розробника немає необхідності так детально відстежувати стан миші, можна скористатися двома іншими методами:
property OnClick: TNotifyEvent;
property OnDblClick: TNotifyEvent;
Перший реагує на клацання кнопкою, другою, — на подвійне клацання.
Кожен елемент управління може змінювати зовнішній вигляд покажчика миші, що переміщається над ним. Для цього використовується властивість
property Cursor: TCursor;
Для управління додатковими можливостями миші ScrollMouse призначено три методи обробника, що реагують на прокрутку:
· property OnMouseWheel: TMouseWheelEvent;
викликається при прокрутці;
· property OnMouseWheelUp: TMouseWheelUpDownEvent;
викликається при прокрутці вперед;
· property OnMouseWheelDown: TMouseWheelUpDownEvent;
викликається при прокрутці назад.
У VCL є клас TMouse, що містить властивості миші, встановленої на комп'ютері. Звертатися до екземпляра класу, який створюється автоматично, можна за допомогою глобальної змінної Mouse. Властивості класу представлені в табл. 1.
Таблиця 1. Властивості і методи класу mouse
Оголошення | Тип | Опис |
property Capture: HWND; | Pu | Дескриптор елементу управління, над яким знаходиться миша |
property CursorPos: TPoint; | Pu | Містить координати покажчика миші |
property Draglmmediate: Boolean; | Ro | При значенні True реакція на натиснення виконується негайно |
property DragThreshold: Integer; | Ro | Затримка реакції на натиснення |
property MousePresent: Boolean; | Ro | Визначає наявність миші |
type UINT = LongWord; property RegWheelMessage: UINT; | Ro | Задає повідомлення, що посилається при прокрутці в ScrollMouse |
property WheelPresent: Boolean; | Ro | Визначає наявність ScrollMouse |
property WheelScrollLines: Integer; | Ro | Задає число прокручуваних ліній |
Ярлики
Призначений для користувача інтерфейс важко представити без ярличків з оперативною підказкою (Hints). Якщо затримати курсор, наприклад, над кнопкою або компонентом палітри самого середовища Delphi, з'являється маленький прямокутник яскравого кольору (вікно підказки), в якому одним рядком сказано про назву цього елементу або пов'язану з ним дію. Delphi підтримує механізми створення і відображення таких ярличків в створюваних програмах.
Властивість, що визначає активність системи підказки у елементу управління:
property ShowHint: Boolean;
Якщо властивість ShowHint встановлена в True, і під час виконання курсор затримався над компонентом на деякий час, у вікні підказки висвічується текстовий рядок з підказкою, яка задана властивістю:
property Hint: string;
Підказка компоненту може бути порожнім рядком — в цьому випадку система шукає в ланцюжку перший батьківський компонент з непорожньою підказкою.
Система оперативних підказок має властивості і методи, загальні для всіх форм в приложенні. Вони зосереджені в Application — глобальному об'єкті, відповідному працюючому приложенню. Всі описані нижче в цьому розділі властивості відносяться не до компоненту, що показує підказку, а саме до Application.
Фоновий колір вікна підказки можна змінити за допомогою властивості
property HintColor: TColor;
У об'єкту Application значення властивості ShowHint потрібно встановлювати під час виконання, наприклад, в обробнику OnCreate головної форми приложення. Воно є таким, що очолює для всієї системи підказок: якщо воно встановлене в значення False, ярлички не метушні кают.
Є ще один спосіб отримання підказки. При зміні поточного елементу управління (тобто при зміні тексту у властивості Hint) в об'єкті Application виникає подія
property OnHint: TNotifyEvent;
Приклад:
procedure TForml.AppHint(Sender: TObject);
begin
Panell.Caption:= Application.Hint;:
end;
procedure TForml.FormCreate(Sender: TObject);
begin
Application.OnHint:= AppHint;
end;
В даному прикладі текст підказки відображатиметься в рядку стану Panell незалежно від значення ShowHint у будь-якого об'єкту — аби цей текст був в наявності. Для цього розділяйте підказку у елементів управління вашого приложення на дві частини за допомогою символу " |" — коротка інформація з'явиться поряд з елементом, а повніша — в рядку стану.
function GetLongHint(const Hint: string): string; function GetShortHint(const Hint: string): string;
У інших компонентів властивість ShowHint інтерпретується системою так: коли курсор миші зупиняється над елементом управління або пунктом меню, і приложення не зайняте обробкою повідомлення, відбувається перевірка, і якщо властивість showHint у елементу або у одного з його батьківських елементів в ієрархії рівне True, то починається очікування.
Якщо в даний момент інші ярлички не показуються, то інтервал часу задається властивістю HintPause:
property HintPause: Integer;
Інтервал часу за умовчанням рівний 500 мс. Якщо в даний момент вже видно ярличок іншого компоненту, то інтервал часу очікування задається властивістю:
property HintShortPause: Integer;
Після закінчення цього часу, якщо миша залишилася над тим же елементом управління, наступає момент ініціалізації вікна підказки. При цьому програміст може отримати управління, передбачивши обробник події об'єкту Application:
property OnShowHint: TShowHintEvent;
TShowHintEvent = procedure (var HintStr: string;
var CanShow: Boolean;
var Hintlnfo: THintlnfo) of object;
Розглянемо параметри обробника події OnShowHint:
· Hintstr — текст, що відображається;
· CanShow — необхідність (можливість) появи підказки. Якщо в змінній CanShow обробник поверне значення False, то вікно підказки висвічуватися не буде;
· Hintinfo — структура, що несе всю інформацію про те, який елемент управління, де і як збирається показати підказку. Її опис:
THintlnfo = record
HintControl: TControl;
HintPos: TPoint;
HintMaxWidth: Integer;
HintColor: TColor;
CursorRect: TRect;
CursorPos: TPoint;
end;
Для показу вікна підказки необхідно ще, щоб у елементу управління або у його предків в ланцюжку рядок Hint був непорожнім. Втім, це можна виправити в обробнику OnShowHint:
procedure TForml.AppShowHint(var HintStr: string;
var CanShow: Boolean;var Hintlnfo: THintlnfo);
begin if HintStr='' then
begin
HintStr:= Hintlnfo.HintControl.Name; Hintlnfo.HintColor:= clRed; CanShow:= True;
end;
end;
Привласнивши цей метод обробникові Application.OnShowHint, встановивши Form.showHint:=True і очистивши всі рядки Hint, отримаємо як підказку ім'я кожного елементу.
Тривалість показу ярличка задається властивістю
property HintHidePause: Integer;
За умовчанням його значення рівне 2500 мс.
Властивість
property HintShortCuts: Boolean;
відповідає за показ разом з текстом ярличка опису "гарячих" клавіш даного елементу управління.
Контрольні питання:
Література:
Дата добавления: 2015-08-09; просмотров: 87 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Определение нормальных напряжений. | | | Оператор GROUP ВУ |