Виправляємо батьківське вікно STL

Виявляється, основні виправлення, які стосуються батьківському вікну, припадають на заголовки (MainFormh) Спочатку давайте додамо код, що описує клас для зберігання точок Перегляньте код, а потім ми обговоримо, що в ньому відбувається:

const int MoveMode = 1

const int DrawMode = 2

class TScribblePoint

{

int FnX int FnY

int FnMode

public: TScribblePoint(void)

{

FnX = 0

FnY = 0

FnMode = MoveMode

}

TScribblePoint (int nMode, int nX, int nY )

{

FnX = nX FnY = nY

FnMode = nMode

}

int GetMode(void)

{

return FnMode

}

int GetX(void)

{

return FnX

}

int GetY(void)

{

return FnY

}

}

Як бачите, клас TScribblePoint досить простий У ньому містяться три змінних – члена класу для координат X і Y точки і режиму, в якому відбувається подія, повязана з цією точкою Крім класу, ми описали дві константи, що позначають два типи режиму

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

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

class TForm2 : public TForm

{

__published: // IDE-managed TMenuItem *File1 TMenuItem *New1 TMenuItem *Exit1 TMenuItem *Update1 TMenuItem *AllWindows1

void __fastcall New1Click(TObject *Sender)

void __fastcall AllWindows1Click(TObject *Sender) void __fastcall Exit1Click(TObject *sender)

private:  // User declarations std::vector&ltTScribblePoint&gt  FvPoints

public: // User declarations

    fastcall TForm2(TComponent *Owner) void ClearPoints(void)

{

FvPointserase (FvPointsbegin(), FvPointsend() )

}

void AddPoint(int nMode, int X, int Y)

{

TScribblePoint point(nMode, X, Y) FvPointinsert (FvPointsend(), point )

}

int NumberOfPoints(void)

{

return FvPointssize()

}

void GetPoint (int Index, int&amp X, int&amp Y, int&amp Mode )

{

X = FvPoints[Index]GetX() Y = FvPoints[Index]GetY()

Mode = FvPoints[Index]GetMode()

}

}

Ці зміни дозволять головній формі працювати з вектором (масивом) крапок Зауважте, що за винятком додавання параметра Mode в методі GetPoint (що потрібно для реалізації нових можливостей) ніякі інтерфейси методів не змінилися Це ще один важливий момент в обєктно-орієнтованому програмуванні Якщо ви коректно напишіть методи доступу (accessor methods) до даних, то ви можете змінювати внутрішню структуру даних, про що клієнтські програми, що використовують ваш обєкт, навіть не знатимуть Якщо ви прослухали кілька курсів з програмування, то ви ймовірно постійно чули про це, але жодного разу не бачили реальної ситуації, де це має значення Ну що ж, тепер ви знаєте, де і навіщо це застосовується

В даному випадку виявляється перевага використання мови C + +, а не C або Visual Basic Якби, наприклад, ви використовували Visual Basic, і використовували змінні для зберігання даних, як ми зберігаємо точки, то вам довелося б знайти всі місця, де використовуються ці змінні, і поміняти їх Насправді, звичайно, такої проблеми у вас би не зявилося, якби ви дійсно програмували на Visual Basic, бо STL підтримується тільки в мові C + + У даному конкретному випадку це також є досить великою перевагою

CBuilder перед Delphi Система Delphi, написана на Object Pascal, має безліч реалізацій векторів (масивів), множин і т д від третіх осіб, але вона не підтримує і, ймовірно, ніколи не підтримуватиме стандарт STL Завіса опускається

Ще одна зміна, яка нам потрібно зробити, стосується дочірніх вікон MDI По-перше, нам потрібно додати параметр Mode у виклик AddPoint в дочірніх вікнах Змініть наступні методи у вихідному файлі Unit1cpp у проекті:

void      fastcall TForm1::OnMouseDown(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, int Y)

{

FbMouseDown = TRUE

/ / Переміститися спочатку в цю точку

Canvas-&gtMoveTo(X,Y)

/ / Надіслати нові дані в головну форму

Form2-&gtAddPoint (MoveMode, X, Y )

}

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

void __fastcall TForm1::OnMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)

{

if  (FbMouseDown )

{

Canvas-&gtLineTo(X,Y)

/ / Надсилаємо нові дані в головну форму

Form2-&gtAddPoint (DrawMode, X, Y )

}

}

Тут насправді дві зміни По-перше, ми додали параметр Mode у виклику методу AddPoint головної форми По-друге, ми прибрали виклик методу ClearPoints, який знаходився в методі OnMouseDown Тепер ми хочемо, щоб користувач міг малювати кілька ліній (це основна зміна в можливостях самого додатка), так що нам більше не потрібно видаляти всі записані точки, коли користувач відпускає кнопку миші і знову натискає її десь ще Щоб відстежити переміщення, власне, і потрібен параметр MoveMode

І, нарешті, остання зміна для дочірніх вікон полягає в додаванні коду, що малює запомненние каракулі, при цьому обробляючи два випадки – малювання і просте переміщення курсору миші, які ми додали в додаток Змініть метод OnPaint дочірнього вікна у файлі Unit1cpp:

void      fastcall TForm1::OnPaint(TObject *Sender)

{

if  (Form2-&gtNumberOfPoints() &gt 0)

{

int X = 0, Y = 0, Mode = DrawMode

/ / Тепер проходимо по всіх точках, отримуємо

/ / Їх координати з головної форми і малюємо їх

for  (int i=0 i&ltForm2-&gtNumberOfPoints() ++i )

{

Form2-&gtGetPoint (i, X, Y, Mode ) switch (Mode )

{

case DrawMode:

Canvas-&gtLineTo (X, Y ) break

case MoveMode:

Canvas-&gtMoveTo (X, Y ) break

}

}

}

}

Тепер функція буде перевіряти режим (малювання або переміщення) і коректно обробляти випадки, коли курсор миші переміщається з натиснутою кнопкою і з відпущеної кнопкою Зауважте також, що нам більше не потрібно окремо обробляти першу точку Тепер важливий режим, в якому точка записана, а не порядок точок Ми таким чином внесли в додаток більш високий рівень абстракції

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

Один невеликий приз для читачів, у яких є компакт-диск, прикладений до книги: на супровідному компакт-диску ви знайдете програму, яка виробляє пошук тексту Вона написана з використанням STL і підтримує пошук по декількох ключовими словами і сортування за кількістю збігів Ця програма з назвою Search знаходиться в каталозі Extras на компакт-диску Для отримання виконуваного файлу програми просто відкрийте її в CBuilder і скомпілюйте Search – консольний додаток, так що вам потрібно запускати його з командного рядка MS-DOS в Windows 95 або NT

Джерело: Теллес М – 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>

*

*