Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Л14.doc
Скачиваний:
9
Добавлен:
30.10.2018
Размер:
202.24 Кб
Скачать

6. Буксування компонентів у вікні програми

У ряді випадків в Windows - програмах використовується переміщення окремих компонентів в полі вікна або якоїсь панелі. Це переміщення може бути переміщенням в якісь певні позиції (це легко здійснюється завданням відповідних значень властивостям Left і Тор) або здійснюватися безперервним буксируванням компоненту за допомогою миші. Простий приклад цього — буксирування компонентів на площині форми в середовищі розробки C++Builder. Подібні завдання виникають достатньо часто в технічних програмах, пов'язаних з компоновкою якогось пристрою, з формуванням якихось схем (наприклад, електричних) і т.п.

Випробувати різні способи буксирування можна в наступному тестовому застосуванні. У ньому на формі розміщено чотири компоненти Image, в які завантажені якісь зображення або частини зображення. Якщо хочете відтворити приклад, в якому на окремих компонентах, як на дитячих кубиках, відтворені фрагменти єдиного зображення, то можете в обробник події форми OnCreate вставити наступний код:

TImage * Pict = new TImage(Form1);

Pict->AutoSize = true;

// В наступному операторі замість ... треба вказати ім'я файлу

Pict->Picture->LoadFromFile(“...”);

Image1->Canvas->CopyRect(Image1->ClientRect, Pict->Canvas,

Rect(0, 0, Pict->Width/2, Pict->Height/2));

Image2->Canvas->CopyRect(Image2->ClientRect, Pict->Canvas,

Rect(Pict->Width/2, 0, Pict->Width, Pict->Height/2));

Image3->Canvas->CopyRect(Image3->ClientRect, Pict->Canvas,

Rect(0, Pict->Height/2, Pict->Width/2, Pict->Height));

Image4->Canvas->CopyRect(Image4->ClientRect,Pict->Canvas,

Rect(Pict->Width/2, Pict->Height/2, Pict->Width, Pict->Height));

delete Pict;

У компонентах Image властивість AutoSize повинна бути встановлена в true.

Почнемо розгляд на цьому прикладі прийомів буксирування. Всі приведені далі обробники подій записані в загальному вигляді. Отже ви можете застосовувати їх одночасно до всіх ваших компонентів Image, а можете до різних компонентів застосувати різні методи, щоб легше було порівнювати них один з одним.

Всі методи використовують декілька глобальних змінних, оголошення яких треба помістити в модулі поза якими - набудь процедурами:

int X0, Y0;

bool move = false;

Змінна move визначає режим буксирування. Вона встановлюватиметься в true на початку буксирування і скидатися в false в кінці. Тому по значенню move можна буде розрізняти переміщення миші з буксируванням і без неї. Змінні Х0 і Y0 будуть потрібно нам для запам'ятовування координат курсору миші.

Один з можливих варіантів рішення нашої задачі — буксирування самого компоненту. Буксирування починається при натисненні лівої кнопки миші на відповідному компоненті Image. Тому початок визначається подією OnMouseDown, обробник якої має вигляд:

void __fastcall TForm1::Image1MouseDown(TObject *Sender,

TMouseButton Button,TShiftState Shift, int X, int Y)

{if (Button != mbLeft) return;

X0=X;

Y0=Y;

move = true;

((TControl *)Sender)->BringToFront() ;

}

Спочатку в цій процедурі перевіряється, чи натиснута саме ліва кнопка миші (чи рівний параметр Button значенню mbLeft, що позначає ліву кнопку). Потім в змінних Х0 і Y0 запам'ятовуються координати миші X і Y у цей момент часу. Задається режим буксування — змінна move встановлюється в true. Останній оператор містить метод BringToFront, для якого подія — ((TControl *)Sender), висуває на передній план відповідний компонент. Це дозволить йому надалі переміщатися поверх інших аналогічних компонентів. Даний оператор не обов'язковий, але якщо його не записати, то в процесі буксирування переміщуваний компонент може опинитися під іншими компонентами.

П6ід час буксирування компоненту працює його обробник події OnMouseMove, що має вигляд:

void __fastcall TForm1::Image1MouseMove(TObject *Sender,

TShiftState Shift, int X, int Y)

{if (move)

{TImage * Im = (TImage *)Sender;

Im->SetBounds(Im->Left + X – X0, Im->Top + У – Y0,

Im->Width, Im->Height);}

}

Він змінює за допомогою методу SetBounds координати лівого верхнього кута на величину зрушення курсору миші (X - Х0 для координати X і Y - Y0 для координати Y). Тим самим підтримується постійне розташування точки курсору в системі координат компоненту, тобто компонент зміщується услід за курсором. Ширина Width і висота Height компоненту залишаються незмінними.

Після закінчення буксирування, коли користувач відпустить кнопку миші, наступить подія OnMouseUp. Обробник цієї події повинен містити всього один оператор:

move = false;

який вказуює програмі на закінчення буксування. Тоді при наступних подіях OnMouseMove їх обробник, приведений раніше, перестане змінювати координати компоненту.

На закінчення відзначимо ще один спосіб буксування, мабуть, найбільш універсальний і простій. Він може бути застосований до будь-яких віконних компонентів, включаючи форми. Пошліться в подіях OnMouseMove всіх компонентів, які ви хочете буксирувати, на наступний універсальний обробник:

const int SC_DRAGMOVE = 0xF012;

ReleaseCapture();

((TControl *)Sender)->Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);

Цей обробник звільняє курсор миші і посилає методом Perform джерелу події Sender повідомлення Windows, відповідне буксируванню.

Можете посилатися на подібний обробник в подіях панелей, кнопок, списків, вікон редагування. Всі подібні компоненти користувач зможе буксирувати, перебудовувавши таким чином інтерфейс програми. Якщо ви пошлетеся на подібний обробник в події форми, то користувач зможе переміщати її по екрану, узявшись за будь - яку її точку, а не тільки за точку в заголовку вікна, як це прийнято в звичайних вікнах Windows.

Контрольні питання:

  1. Які події миші пов’язані із її пересуванням, а які із клацанням по кнопкам?

  2. Із якими діями користувача може бути пов’язана подія OnClick?

  3. Які події, пов’язані із мишею повертають координати положення курсору?

  4. У чому полягає відмінність подій, пов’язаних із клавіатурою?

  5. Яким чином можна перевіряти натиснену клавішу клавіатури?

  6. Які властивості визначають пересування даних між компонентами?

  7. Як у програмі можна реалізувати плаваючі інструментальні панелі?

  8. Яким універсальним способом можна реалізувати буксування віконних компонентів?

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]