Реалізація карт повідомлень C + + Builder

На рис 49 представлена ​​форма, яка покаже міць системи карт повідомлень в CBuilder Для створення цієї форми додайте панель стану у верхню частину форми, встановивши властивість Alignment (вирівнювання) панелі стану в alTop Це змусить панель стану «отесть» частину простору форми і уріже клієнтську область форми Це необхідно, тому що якщо ми розмістимо панель стану внизу, то при вертикальній прокрутці форми (чим ми збираємося займатися) панель стану буде знаходиться на дні віртуальної форми, тобто досить далеко Зараз панель стану буде видна завжди, і її можна використовувати для відображення інформації про поточний стан форми

Рис 49 Форма прикладу карт повідомлень

Подбавши про панелі стану, наступним кроком нам треба встановити смуги прокрутки у форми, щоб ми могли отримувати від них дані Щоб змусити форму відображати смуги прокрутки, виберіть форму в Object Inspector Знайдіть властивість VertScrollBar (вертикальна смуга прокрутки) і клацніть двічі в лівій частині таблиці Object Inspector Це розкриє властивість для показу подсвойств Поміняйте подсвойство Range (діапазон) на 1000 цього достатньо, щоб смуга прокрутки зявилася

Перейдіть до властивості HorzScrollBar (горизонтальна смуга прокрутки) і повторіть операцію Коли ви закінчите, у форми зявляться обидві смуги прокрутки – вертикальна і горизонтальна Тепер перейдіть до панелі стану і клацніть праворуч від властивості Panels (секції) Ми збираємося додати дві невеликих секції для відображення віртуальних позицій рядка і стовпчика у формі Додайте три секції в панель стану Залиште порожнім текст в секціях

У цей момент ми готові почати писати код для обробки повідомлень Перед цим давайте розберемося, що ж таке карти повідомлень

Загальний синтаксис карти повідомлень такий: BEGIN_MESSAGE_MAP

MESSAGE_HANDLER(message,  function) END_MESSAGE_MAP(object)

де message – повідомлення Windows, яке ви хочете обробити Зазвичай повідомлення Windows виглядають приблизно так: WM_xxx function – функція на рівні обєкта, яку ви хочете використовувати для обробки повідомлення Функції, обробні повідомлення, зазвичай мають один параметр – посилання на обєкт типу TMessage object – клас, для якого ви визначаєте цю карту повідомлень (TForm, TListBox, ..)

Ми хотіли б додати два обробника повідомлень вертикальної і горизонтальної прокрутки форми Модифікуйте заголовки (Unit1h) для форми таким чином Спочатку зробіть зміни (виділені підсвічуванням), а потім ми обговоримо, що ці зміни роблять:

//———————————————————-

#ifndef Unit1H

#define Unit1H

//———————————————————-

#include &ltvcl\Classeshpp&gt

#include &ltvcl\Controlshpp&gt

#include &ltvcl\StdCtrlshpp&gt

#include &ltvcl\Formshpp&gt

#include &ltvcl\ComCtrlshpp&gt

//———————————————————-

class TForm1 : public TForm

{

__published:  // IDE-managed Components TStatusBar *StatusBar1

void __fastcall HandlePaint(TObject *Sender) private: // User declarations

void __fastcall HandleVScroll(TMessage&amp Msg) void __fastcall HandleHScroll(TMessage&amp Msg) int FnStartLine

int FnStartCol

public:   // User declarations

__fastcall TForm1(TComponent* Owner) BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_VSCROLL,HandleVScroll) MESSAGE_HANDLER(WM_HSCROLL,HandleHScroll)

/ / Можете додати сюди

/ / Будь-яку кількість додаткових обробників

END_MESSAGE_MAP(TForm)

}

//———————————————————–

extern TForm1 *Form1

//———————————————————–

#endif

Перша частина виправлень оголошує два методу (HandleVScroll і HandleHScroll), які ми будемо використовувати як обробники повідомлень в цій формі Обидва методи приймають по одному параметру – посиланню на обєкт типу TMessage, який містить вхідну інформацію про повідомлення Зауважте, що так як це обробники повідомлень і тому перекривають обробники в низлежащий VCL, то потрібно використовувати для цих методом модифікатор __ fastcall

Змінні FnStartLine і FnStartCol (члени класу TForm1) будуть використані для зберігання того, наскільки далеко ми прокрутили форму відповідно в вертикальному та горизонтальному напрямку Також ці змінні будуть використовуватися для відображення інформації в панелі стану і для визначення того, що буде промальовано на формі

Зазвичай ви обробляєте прокрутку форми, тому що ви хочете керувати промальовуванням тексту, графіки або інших даних на формі Для цього ми перевизначити промальовування форми, додавши обробник події OnPaint У Object Inspector додайте обробник події OnPaint і дайте йому імя HandlePaint Перейдіть в редактор і додайте в обробник події HandlePaint наступний код:

void __fastcall TForm1::HandlePaint(TObject *Sender)

{

int x = 0 int y = 0

for ( int i=FnStartLine i&lt100 ++i)

{

String s = Це рядок + String (i) int nHeight = Canvas-> TextHeight (s) Canvas-> TextOut (x, y, s)

y += Height

}

}

Як бачите, ми просто відображаємо рядки тексту на робочому просторі форми Рядки тексту відображають номер рядка, починаючи з поточної стартовою рядки і збільшуючись до 100 відображених рядків Кожен рядок тексту буде зображена на окремому рядку форми, так як ми збільшуємо вертикальну (y) координату на висоту попереднього рядка

Обробка вертикальної прокрутки – не надто складна робота, якщо ви розумієте, як виглядають повідомлення, які ви отримуєте Зазвичай якщо ви хочете обробити повідомлення у вигляді карти повідомлень, то вам потрібно небудь знати про те, як виглядають повідомлення в Windows API Наприклад, для повідомлення прокрутки секція WParam обєкта TMessage міститиме код, що показує, що зробив користувач Це код може показувати або одинарне переміщення в смузі прокрутки (вгору або вниз), або переміщення на сторінку (вгору або вниз), або перетягування покажчика на смузі прокрутки Ми не збираємося возитися з перетягуванням покажчика в цьому прикладі, так як це не дуже важливо, поки у вас не так вже й багато тексту для обробки Ми займаємося прокруткою вгору і вниз на один рядок або сторінку, так як ми всього лише відображаємо випадкові рядки тексту на формі Ось повний код для обробника вертикальної прокрутки:

void __fastcall TForm1:HandleVScroll(TMessage&amp Msg)

{

int nStartPos = FnStartLine

switch( MsgWParam )

{

case SB_LINEUP: if ( FnStartLine ) FnStartLine– break

case SB_LINEDOWN:

FnStartLine++ break

case SB_PAGEDOWN: FnStartLine += 10 break

case SB_PAGEUP:

if ( FnStartLine &lt 10 ) FnStartLine = 0

else

FnStartLine —= 10 break

}

/ / Якщо позиція змінилася, перемальовувати if (FnStartLine = nStartPos)

Invalidate()

StatusBar1-&gtPanels-&gtItems[0]-&gtText  =

“Ряд: + String (FnStartLine) StatusBar1-> Panels-> Items [1] -> Text =

“Кол: + String (FnStartCol)

}

Цей обробник повідомлення самодостатній, так як він отримує повідомлення і працює з ним, не звертаючись до низлежащий оброблювачу з VCL Як тільки ми визначили, використовуючи код повідомлення, що саме зробив користувач в смузі прокрутки, ми просто збільшуємо або зменшуємо індикатор вертикальній позиції, який ми зберігаємо в змінній FnStartLine Закінчивши з цим, ми перевіряємо, чи однакові початкова позиція і отримана Якщо ні, як це майже завжди і буде, то ми перемальовували форму, що перепише рядки тексту, відображаючи произошедшую прокрутку тексту І, нарешті, ми оновлюємо текст в секціях панелі стану, містять поточний номер ряду і колонки

Як і з вертикальна смуга прокрутки, горизонтальна смуга передає ту ж інформацію, використовуючи ті ж коди Єдина відмінність в нашому обробнику – у тому, що ми працюємо з горизонтальною позицією, а не з вертикальною Зауважте, що ми нічого не робимо з горизонтальною прокруткою в цьому прикладі, так що немає потреби перемальовувати форму Ось повний код обробника горизонтальної прокрутки:

void __fastcall TForm1:HandleHScroll(TMessage&amp Msg)

{

int nStartPos = FnStartCol

switch( MsgWParam )

{

case SB_LINEUP: if ( FnStartCol ) FnStartCol– break

case SB_LINEDOWN: FnStartCol++

break

case SB_PAGEDOWN: FnStartCol += 10 break

case SB_PAGEUP:

if ( FnStartCol &lt 10 ) FnStartCol = 0

else

FnStartCol —= 10

break

}

StatusBar1-&gtPanels-&gtItems[0]-&gtText  =

“Ряд: + String (FnStartLine) StatusBar1-> Panels-> Items [1] -> Text =

“Кол: + String (FnStartCol)

}

Останнє додавання у форму – ініціалізація змінних-членів класу, яка робиться в конструкторі Додайте наступний код в конструктор для завдання стартових значень ряду і колонки перед промальовуванням форми:

__fastcall TForm1::TForm1(TComponent *Owner)

: TForm(Owner)

{

FnStartLine = 0

FnStartCol  = 0

}

Ось і все відносно цього прикладу карт повідомлень Як бачите, обробка карт повідомлень не особливо складна Ви просто додаєте елементи в карту, точно так само, як ви б це робили в Visual C + + або Borland C + + У CBuilder немає вбудованої підтримки автоматичного додавання елементів в карту повідомлень, в основному тому, що додавання елемента в карту повідомлень має бути останнім притулком зневірених, а не першим кроком, як це відбувається в каркасних системах

Ви напевно, помітите, що рідко (якщо взагалі коли-небудь) використовуєте карти повідомлень у своїх додатках Розробники компонентів, ймовірно, знайдуть це більш звичайним, але проте рідкісним справою Уважно вивчіть надані події у компоненту, перед тим, як ви вирішите обробляти повідомлення безпосередньо, через карту повідомлень Повинна бути дуже хороша причина, по якій у компонента відсутня подія, повязане з повідомленням

Хоча VCL – досить потужна система, існує ряд додатків, яким потрібен доступ до таких речей, які не реалізовані в VCL безпосередньо Одна з таких додаткових речей – можливість використовувати список Windows з невеликими змінами Деякі програми хочуть змінити колір кожного елемента в списку, іншим потрібно змінювати шрифт, використовуваний при відображенні елементів списку, а деяким навіть потрібно малювати щось типу зображення або картинки разом з текстом у списку, щоб дати короткий опис даних, що зберігаються в цьому елементі списку Система VCL робить написання таких речей дивно простим, враховуючи, що ви щось знаєте про повідомлення Windows і потрібних викликах API У цьому прикладі ми покажемо вам, як налаштувати список для відображення елементів в такому вигляді, який вам потрібен, включаючи зміна шрифту, кольору, відображення картинки разом з кожним елементом у списку Є насправді два шляхи, якими ви можете реалізувати ті види змін, про які ми тут говоримо По-перше, ви можете обробляти промальовування списку у формі, на якій він розташований Цей тип списку зазвичай залежить від форми Другий тип списку, що має таку поведінку, реалізується на рівні компонентів Наслідуючи новий компонент від стандартного списку Windows (реалізується через TCustomListBox), ви можете потім з легкістю використовувати цей список в багатьох формах і багатьох додатках У цьому прикладі ми розберемося з першим випадком: промальовування списку у формі, на якій він живе

Джерело: Теллес М – Borland C + + Builder Бібліотека програміста – 1998

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*