
IntToStr()
Найбільш часто використовується функція. Як ви вже знаєте, вона приймає в якості параметра ціле число, і повертає його у вигляді рядка. Хотілося б відзначити ще одну особливість: ця функція призначена для будь-якого цілого числа, не обов'язково Integer. Якщо у вас є невелика Byte, Word, Cardinal або Int64, все це змінні цілого типу, і для будь-якої з них годиться функція IntToStr().
Прикладивикористання:
var b : Byte; w : Word; i : Integer;
begin b := 5; w := 10; i := 20;
Edit1.Text := IntToStr(b); Edit2.Text := IntToStr(w); ShowMessage(IntToStr(i)); end;
StrToInt()
Цяфункціянавпаки, приймаєвякостіпараметрарядок, щозображаєцілечисло, іповертаєйогоувиглядіцілогочисла. Все, що було сказано про типи даних у функції IntToStr(), справедливо і для цієї функції. Прикладивикористання: var b : Byte; w : Word; i : Integer;
begin b := StrToInt(Edit1.Text); //увагу! Якщокористувачвведечисло
//більше 255, станетьсяпомилка! w := StrToInt('50000'); i := StrToInt(Edit2.Text); end;
Якбачите, діїцихфункційдужесхожі, лишевостанньомувипадкудоводитьсязастосовуватиобережність, щобнеперевищитидіапазонможливихзначень. Якщо ви заздалегідь не знаєте, яке число введе користувач, краще використовувати Integer, або Cardinal, якщо число без знаку. Економія пам'яті інший раз може викликати серйозні помилки в програмі.
FloatToStr()
Ця функція приймає в якості параметра дійсне число (тобто, число з комою), і повертає його у вигляді рядка. Приклади застосування майже аналогічні функції IntToStr(), однак є одна особливість - якщо після коми у Вас є тільки нулі, то функція поверне рядок у вигляді цілого числа:
s := FloatToStr(125,00); // результат: '125'
Ця функція також призначена для всіх типів запакованих чисел.
StrToFloat()
Ця функція приймає в якості параметра рядок у вигляді речового або цілого числа, і повертає це дійсне число. Приклад:
f := StrToFloat('125'); //результат: 125,0
FormatFloat()
Ця функція за своїм призначенням схожа на функцію FloatToStr(), однак вона є набагато більш потужним інструментом. Ця функція не тільки возвращает дійсне число як рядка, але ще і дозволяє задати бажаний формат цього рядка. У попередніх прикладах ми говорили, що функція FloatToStr() замість рядка ‘125,00’ виведе ‘125’. А якщо потрібно все-таки ‘125,00’? Таке часто трапляється, особливо в фінансової документації. Для цих цілей і створена функція FormatFloat.
Вона має два параметра - рядок формату і саме число. Рядок може містити наступні формати:
Таблиця 15.1. Можливі формати FormatFloat().
Рядок, що вказується у форматі |
|
Приклади чисел |
| ||
|
1234 |
-1234 |
0,5 |
0 | |
0 |
1234 |
-1234 |
1 |
0 | |
0.00 |
1234,00 |
-1234,00 |
0,50 |
0,00 | |
#.## |
1234 |
-1234 |
0,5 |
0 | |
0,000.00 |
1 234,00 |
-1 234,00 |
0,50 |
0,00 |
Є й інші варіанти форматів, наприклад, для представлення числа в експонентної формі, але вони, як правило, не використовуються. Пояснимо рядок форматів докладніше.У першому випадку показані варіанти повертаються рядків, якщо рядок форматів взагалі не вказана (порожній рядок). «Решітка» (#) працює також як «нуль», з тією різницею, що якщо на цьому місці не виявиться цифри, то «решітка» нічого не виведе, а «нуль» підставить в це місце нуль. Знак кома тут вказують для поділу тисячних частин. Наприклад, мільйон буде виглядати як рядок ‘1 000 000’. Зауважимо, що саме число цей формат не має жодного впливу, він потрібен лише для того, щоб виводити кількість в зручній формі у вигляді рядка.
Прикладивикористання:
procedure TForm1.Button1Click(Sender: TObject); var
f : Real;
begin
f := 1234567.00;
ShowMessage(FormatFloat('0,000.00' ,f)); //результат: "1 234 567,00" ShowMessage(FormatFloat('', f)); //результат: "1234567" end;
Інші перетворення
Іноді, щоб перетворити один тип даних в інший, достатньо вказати цей тип:
var
p : Char; s : String; begin
p := 'Строка'; s
:= String(p); p
:= PChar(s);
В інших випадках, схожі типи даних можна просто надавати один одному. Компілятор в цьому випадку сам зробить потрібне перетворення. Наприклад, цілий тип даних можна присвоїти речовому числа, компілятор сам підставить нуль. А от навпаки не вийде, адже дійсне число розглядається, як два цілих числа:
var
f : Real;
i : Integer;
begin
i := 12;
f := i; //Результат: 12,0
i := f; //Ошибка! Такнельзя
Підстановка значень
Дуже часто в мовах програмування для елегантності коду підставляють одне значення замість іншого. Порівняйте два приклади:
var
s : String; i : Integer;
begin
s := Edit1.Text; i := StrToInt(s); end;
Все, що ми зробили в даному прикладі, так це привласнили змінної i число з Edit1, яке зберігалося там у вигляді рядка. Але для цього нам довелося спочатку занести цей рядок у строкову змінну s, і вже її обробляти функцією StrToInt(). Такий приклад цілком буде працювати, проте він дуже громіздкий. Набагато елегантніше виглядає наступний код:
var
i : Integer;
begin
i := StrToInt(Edit1.Text);
end;
В результаті вийшло менше змінних, менше роботи для процесора, менше займаної пам'яті і коротше код! А нерідко вживають набагато більш складні вирази, наприклад:
i := StrToInt(Memo1.Lines[5]) + StrToInt(Edit1.Text);
s := IntToStr(StrToInt(Memo1.Lines[5]) + StrToInt(Edit1.Text));
У першому рядку в цілу змінну i ми вивели суму цілих чисел, які зберігалися у вигляді рядка в Edit1 і в п'ятому рядку Memo1.
Другий рядок складніше. Тут ми спочатку перевели ці ж числа в цілі числа і додали їх, потім знову перетворили в рядок, щоб записати суму цих двох чисел в строкову змінну s. Спочатку вам такий код може здатися дуже складним, але спробуйте застосовувати такий підхід у своїх програмах, і ви швидко звикнете до нього, і самі помітите, що такий код більш компактний і елегантний. Візьміть другий рядок. Такий же результат можна було б домогтися спрощеними виразами:
i := StrToInt(Memo1.Lines[5]);
k := StrToInt(Edit1.Text); m :=
i + k; s := IntToStr(m);
Все це буде працювати, і на перший погляд, здається простіше. Однак, чотири рядки замість однієї! І чотири змінних замість однієї! Будь-який програміст назве такий код потворним і дилетантським. Так що звикайте до гарного і компактного коду!
Глобальна зміннаDecimalSeparator
Це неявна глобальна мінлива. Неявна, тому що ви її ніде не описували, і в коді модуля її немає. Однак Delphi самостійно створює цю і деякі інші глобальні змінні для кожного нового проекту, так що ви спокійно можете нею користуватися.
Що це за мінлива? Вона зберігає один символ - роздільник між цілої і десятковою частиною дійсного числа. І роздільником може бути або точка, або кома. У російських версіях Windows найчастіше використовується кома, хоча можна переналаштувати операційну систему так, що буде крапка. А ось в англійських ОС - точка. Якщо ви робите програму тільки для особистого використання, то сміливо можете влаштовувати перевірку на введення запакованих чисел, і як роздільник вказувати кому. Але якщо ви робите програму для клієнта, то не можете бути впевнені, який розділювач там стоїть. Адже він може використовувати вашу програму і на англійській версії Windows! Тоді програма буде видавати помилку відразу, як справа дійде до введення дійсного числа.
Вихід: під час перевірки використовувати не кому або точку, а глобальну змінну DecimalSeparator, яка зберігає потрібний розділювач.
Створіть новий проект, і встановіть на нього компонент Edit для введення дійсного числа. Нижче киньте Memo, сюди ми будемо виводити це число, відформатований різними способами за допомогою FormatFloat(). Ще нижче - кнопку для того, щоб почати заповнювати Memo. Насамперед ми з вами встановимо «захист від дурнів» - перевірку компонента Edit, щоб користувач не зміг ввести туди нічого, крім цілого або дійсного числа. При цьому ми будемо як роздільник використовувати змінну DecimalSeparator, і крім того, перевіримо, щоб вона не зустрічалася більше одного разу. Потім цю перевірку без змін ви зможете застосовувати в будь-яких подальших ваших проектах, де потрібно необхідна перевірка. Для Edit1 створюємо обробник подій OnKeyPress, яке викликається кожного разу, коли користувач натискає клавішу при введенні тексту в компонент Edit. Впишемо в тіло обробника наступний код:
caseKeyof
'0'..'9': ; //числаразрешаем
//еслиразделителяещенет - выводимправильныйразделитель, //иначеничегоневыводим
',' , '.' : if Pos(DecimalSeparator, Edit1.Text)= 0 then Key := DecimalSeparator else Key := Chr(0); #8 : ; //backspace
//разрешаемотрицательноечисло, еслиминусидетпервымсимволом
'-': if (Pos('-', Edit1.Text) = 1) and
(Length(Edit1.Text) >0) then Key := Chr(0); #13 : Button1.SetFocus; else Key := Chr(0); end; //case
Цей код вимагає деяких пояснень. Подія OnKeyPress компонента Edit самостійно створює параметр Key, це мінлива типу Char, тобто символ. У цієї змінної міститься символ, введений користувачем. Оскільки символ - яка перераховується значення (тобто, він може бути від 0 до 255), можна використовувати конструкцію case. Як селектора вказуємо змінну Key, а в якості значення вказуємо те значення, яке там може знаходитися. Рядок
'0'..'9': ; //числаразрешаем
показує, що якщо були введені символи від 0 до 9, то нічого не відбувається (після знаку «:» немає діючих операторів). Тут ми можемо отримати нове правило: можна показувати діапазон числових або символьних значень через знак «..», наприклад, ‘a’..’z’; 1..9. Далі йдуть рядки:
',' , '.' : if Pos(DecimalSeparator, Edit1.Text)= 0 then Key
:= DecimalSeparatorelseKey := Chr(0);
Цей код дає нам нове правило: через кому можна вказати можливі значення. Тобто, блок коду буде виконуватися, якщо користувач ввів або кому, або точку. У самому блоці коду ми перевіряємо: чи нема вже в рядку потрібного роздільника? Якщо немає (Pos() повернула нуль), то ми записуємо в змінну Key потрібний розділювач, інакше присвоюємо їй нульовий символ (тобто користувач нічого не ввів). При цьому неважливо, крапку або кому ввів користувач - роздільник все одно буде правильним.
Далі, якщо користувач ввів символ #8 (натиснув <BackSpace>), то нічого не робимо - тобто, дозволяємо цей символ. Треба ж залишити йому можливість редагувати свій текст, виправляти помилки. І знову правило: можна вказати номер символу, використовуючи функцію(Chr), або просто після символу «#»:
Key := Chr(8); Key := #8;
В обох випадках, в змінну Key потрапить символ, який у таблиці символів йде під номером 8, тобто <BackSpace>.
Далі ми дивимося, не мінус чи ввів користувач? Якщо так, то дивимося, яка довжина рядка. Адже якщо довжина рядка більше нуля, значить, в неї вже є символи, і мінус дозволяти не можна. У разі ж, якщо рядок ще не містить нічого, то мінус припустимо, і блок коду if не виконається.
Якщо користувач натиснув <Enter>, Key буде містити символ #13. Зазвичай користувач натискає <Enter>, коли він закінчив введення тексту. Рядок
#13 : Button1.SetFocus;
передає фокус (тобто, виділення компонента) на кнопку, якщо натиснути клавішу <Enter>.Ну і наприкінці ми зазначаємо, що в будь-якому іншому випадку (користувач набрав букву або якоїсь іншої неприпустимий знак) змінної Key присвоюється нульовий символ. Комп'ютер відреагує так, ніби користувач нічого і не вводив.
У процедурі натискання кнопки пишемо такий код:
var
f : Real;
begin
f := StrToFloat(Edit1.Text);
Memo1.Lines.Add(FormatFloat(, f)); Memo1.Lines.Add(FormatFloat('0,000.00', f)); Memo1.Lines.Add(FormatFloat('#,###.##', f)); Memo1.Lines.Add(FormatFloat('#.##', f)); Memo1.Lines.Add(FormatFloat('0.00', f));
Memo1.Lines.Add(' '); //разделитель
end;
Тут все зрозуміло - спочатку перетворимо отримане число у вигляді рядка, в дійсне число. Потім це число виведемо в Memo, надавши йому різні формати. Збережіть приклад, зберіть його, і подивіться, як працює програма. У подальшій практиці вам не раз доведеться ставити подібну «захист від дурнів», цей приклад події OnKeyPress можна буде просто копіювати в будь-яку нову програму.
Лекція 16. Кнопки з зображеннями і маскувальне поле вводу
Кнопки BitBtn
Такі кнопки використовують, в основному, для прикрашення програми. Вони відрізняються від звичайної кнопки Button насамперед тим, що разом з написом на кнопку можна вивести і картинку. Кнопка з картинкою, безумовно, виглядає орнаментом.
Відкрийте новий проект і встановіть на нього кнопку BitBtn з вкладки Additional панелі компонентів. У властивості Caption цієї кнопки напишіть «Відкрити файл». Далі, виберіть властивість Glyph - це властивість спадне, потрібно натиснути на кнопочку з трьома точками в цій властивості, щоб відкрився список. Відкрився редактор зображень. Натиснемо кнопку Load (Читати). За замовчуванням відкривається стандартна папка з проектами Delphi, але картинок тут немає. При установці Delphi-7 картинки встановлюються в папку
C:\Program Files\Common Files\Borland Shared\Images\Buttons
Відкрийте папку, в редакторі. Як тільки ви виберіть картинку (тобто один раз клацніть по ній), у правій частині вікна з'явиться малюнок цієї картинки. Тут ви бачите два зображення для кожної кнопки - перше зображення буде активною (доступною) кнопки, друге - для неактивною. Тепер у вас є можливість прогулятися по колекції зображень за допомогою кнопок керування курсором, вибираючи відповідний для кнопки зображення. Оскільки ми хочемо зробити кнопку для відкриття файлу, то виберемо стандартне для цього зображення у файлі «FILEOPEN». Картинка не дуже приваблива, але поки що скористаємося їй. Вибравши файл, натисніть кнопку «Відкрити». Зображення потрапило в редактор зображень. Тепер, щоб прийняти зображення, натиснемо кнопку «ОК». Якщо картинка разом з написом не поміщається на кнопці, то збільшити ширину кнопки.
Киньте ще одну кнопку BitBtn, у властивості Caption вкажіть «Закрити файл»та спробуйте самостійно підібрати картинку для цієї кнопки.
У цій кнопці нам може знадобитися кілька властивостей.
Властивість Layout визначає, де буде знаходитися картинка. За умовчанням вона зліва - blGlyphLeft, але можна встановити зображення і праворуч, а також зверху або знизу, щоправда, в цьому випадку доведеться коректувати висоту кнопки.
Властивість Margin також визначає положення зображення і написи. За замовчуванням воно одно «-1». Якщо ж вказати значення більше 0, зображення і зображення будуть рухатися вправо на вказану кількість пікселів.
Властивість Spacing за замовчуванням дорівнює 4. Це кількість пікселів, що відокремлюють зображення від напису. Ви маєте можливість змінювати цю відстань за своїм розсудом.
Ще одна цікава властивість - Kind. Це властивість визначає поведінку кнопки в деяких випадках. За замовчуванням воно одно bkCustom (замовлений). Тобто, в даному випадку ви самі визначаєте поведінку кнопки - як виглядає зображення, що написано на кнопці, що буде зазначено у обробнику натискання на кнопку. Однак спробуйте встановити на форму ще одну таку кнопку, і властивості Kind вибрати bkClose. Відразу ж з ’ явилося стандартне зображення Delphi закриття форми, і на кнопці написано Close Закрити. Змініть текст у властивості Caption на російський варіант, потім збережіть проект і відкомпілюйте його. Натисніть на цю кнопку, і форма закриється.
Взагалі то зазвичай не рекомендують використовувати властивість Kind, бажано самим програмувати поведінку кнопки. По-перше, ви можете захотіти для цієї кнопки вибрати інше зображення, по-друге, процедура закриття форми може бути набагато складніше звичайної рядка «Close;», адже якщо є відкритий файл або база даних, їх спочатку треба закрити, якщо є якісь незбережені дані, їх потрібно зберегти перед закриттям форми. Втім, використовувати цю властивість чи ні - справа смаку кожного програміста.
Про картинках. Стандартна колекція зображень для кнопок у Delphi не вражає красою і багатим вибором. Однак ви можете знайти в Інтернеті дуже багато безкоштовних колекцій таких картинок, і скачати їх. Далі вибирайте ті зображення, які на ваш погляд виглядають привабливо.
Якщо ж ви відчуваєте в собі талант художника, можете намалювати зображення самі, скориставшись редактором зображень ImageEditor, який встановлюється разом з Delphi.
Рада. Пам'ятайте, що вся програма повинна виглядати в загальному стилі. Якщо ви змінили колір головною форми, бажано змінити його і у всіх дочірніх форм на такий же. Якщо на головній формі ви використовуєте замість звичайних кнопок кнопки TBitBtn, і вибрали для них яку то сторонню колекцію, то бажано використовувати такі ж кнопки і в інших формах, і використовувати картинки з тієї ж колекції.
Інші властивості кнопок
Є ще кілька властивостей, загальних для всіх кнопок, які вам необхідно знати.
Змініть властивість Caption кнопки «Відкрити файл» - поставте перед першою літерою символ&». На кнопці буква «Про» виявилася підкресленою. Цим ви задали для кнопки «гарячі клавіші», тобто тепер все одно - натиснути на цю кнопку, або натиснути клавіші <Alt + O>. Запам'ятайте - символ&» перед буквою задає гарячу клавішу. Ви можете поставити його перед будь-якою буквою, не обов'язково перед першою. Спробуйте самі!
Властивість Cancel за замовчуванням дорівнює False. Якщо ж у ньому встановити True, то при виконанні програми натискання кнопки <Esc> буде виконувати ту ж дію, що і натискання на цю кнопку. Це властивість бажано змінювати для кнопок «Скасувати» в різних діалогових вікнах.
Властивість Default, встановлене у True, робить кнопку головною за замовчуванням. Якщо користувач натисне <Enter>, це буде еквівалентно натискання на цю кнопку. Тут є виняток - якщо в цей момент у фокусі буде інша кнопка, то натискання на <Enter> викличе все ж обробник подій кнопки, що була у фокусі.
Властивість ModalResult іноді використовується в модальних формах. За замовчуванням воно одно mrNone, тобто, нічого. Проте ви можете вибрати будь-яке значення з цього списку. Припустимо, у модальної формі ви встановили кнопки «Так», «Ні» і «Скасувати». Тоді у властивості ModalResult цих кнопок ви можете встановити значення mrYes, mrNo і mrCancel. При цьому обробник подій для цих кнопок створювати не потрібно - натиснення на будь-яку кнопку закриє форму. А в момент закриття модальної форми, властивості ModalResult цієї форми запишеться значення ModalResult кнопки, яка закрила форму. Далі, після виклику цієї форми ви можете написати перевірку, яка кнопка була натиснута:
Form2.ShowModal;
if Form2.ModalResult = mrIgnore then
ShowMessage('Нажали "Игнорировать"');
Ось, власне, і все, що потрібно знати про кнопках. Залишилися ще кнопки SpeedButton, вони призначені для створення панелей інструментів, і про них ми поговоримо пізніше.
Компонент MaskEdit
Цей компонент подібний до звичайного Edit, але призначений для завдання маски введення користувачем даних. Дуже часто виникає необхідність поставити правильний формат для введення користувачем якихось даних, і тут MaskEdit буде незамінною.
Дія цього компонента краще вивчати на прикладі. Створіть новий додаток. На форму встановіть компонент Label, у властивості Caption якого пропишіть «Введіть дату:». Зліва від нього помістіть компонент MaskEdit. Як бачите, більшість властивостей цього компонента відповідають компоненту Edit, і це не дивно - адже MaskEdit стався від простого Edit і успадкував всі його властивості.
Найцікавіше властивість цього компонента - EditMask. Клацніть по ньому, а потім по кнопочку, яка відкриває редактор.
Рис.16.1. Редактор маски компонента MaskEdit
У рядку InputMask ви можете задати потрібний формат (маски). У полі SampleMask ви бачите типи масок і приклади формату. Вибравши тут потрібний тип, ви відразу ж задасте маску для введення. У рядку TestInput ви можете побачити, як буде відбуватися введення даних, тобто, протестувати введення. Встановити маску можна не тільки вибором її типу, але і вказавши її самостійно. Наприклад, ви бажаєте створити маску для введення телефонного номера. Тоді в рядку InputMask ви пишете рядок «999-99-99». Цифра 9 вказує, що в цьому місці повинна бути будь-яка цифра.
Поле CharacterforBlanks вказує, який символ тут буде вказуватися в місці введення. За замовчуванням це знак підкреслення. Тобто, якщо ми залишимо цей символ і виберемо тип Date, користувач побачить:
__.__.__
Тут є один мінус: маску для введення ми задали, однак перевірка правильності не проводиться, тобто користувач може вписати «20.20.07», а 20-го місяця не буває. Так що перевірку правильності потрібно буде проводити самостійно.
Давайте змінимо маску в полі InputMask, і напишемо «99.99.9999 р.». Створіть таку маску, зберіть програму і побачите, що користувач зможе ввести тільки цифри, причому «р» вже буде присутній в рядку.
Спробуйте самостійно зробити маску для введення номера телефону разом із кодом вашого міста.
Ще одна цікава властивість, загальні для компонентів Edit і MaskEdit, це властивість PasswordChar - символ введення пароля. За замовчуванням він дорівнює «0»#, тобто жодного символу. Якщо ж ми вкажемо символ «*», як це прийнято за замовчуванням у Windows, під час роботи програми всі символи, які буде вводити користувач, в цьому рядку буде відображатися як зірочки. Причому на сам текст це не матиме ніякого впливу, просто його не буде видно в момент введення.
Однак замість зірочок можна використовувати й інші символи. Встановіть на форму компонент Edit. У властивості Font виберіть шрифт Windings. А у властивості PasswordChar вкажіть «#74». Тоді всі введені символи будуть відображатися, як усміхнені обличчя. Вибрати потрібні шрифт і символ ви можете з допомогою MS Word, наприклад. Виберіть там команду Вставити - символ». У вікні виберіть шрифт, потім виберіть символ. В поле «код символу» буде відображатися код обраного символу, його і вкажіть після знаку#» в PasswordChar. Ви можете вказати там будь-який символ, але краще дотримуватися загальноприйнятих стандартів, щоб не бентежити користувача.
Самостійно придумайте і реалізуйте додаток, використовуючи кнопки із зображеннями і хоча б одну маскувальне поле введення.
Лекція 17. Дати
Логічні операнди
В умовних перевірках, таких як if, while або repeat часто буває недостатнім перевіряти тільки одну умову. Можна скористатися вкладенням перевірок, як у наведеній у прикладі конструкції:
if a > 0 then
if b <> a then begin
команда 1;
команда 2;
end; //if 2
В цьому коді ми перевіряємо, чи правда a більше нуля. Якщо так, то перевіряємо, не дорівнює чи b і a. І тільки в тому випадку, якщо друга умова також поверне Істину, виконуватись зазначені команди. Таких вкладень може бути скільки завгодно, і ними нерідко користуються.
Є й інший спосіб численних перевірок. Для того, щоб можна було перевіряти більше одного умови, існують логічні оператори AND, OR і NOT. Оскільки ці оператори мають найвищий пріоритет в обчисленнях, умови необхідно укладати в дужки.
Оператор AND (І) перевіряє дві умови, і повертає істину тільки в тому випадку, якщо обидві умови повернуть істину. Погляньте на попередній приклад, і подивіться, як його можна написати з оператором AND:
if (a > 0) and (b <> a) then begin
команда 1;
команда 2; end; //if
Оператор OR (Або) повертає істину в тому випадку, якщо хоча б одна з умов поверне істину:
if(3 > 5) or(5 > 4) then…//результат - истина, таккак 5 больше 4
Оператор OR перевіряє спочатку ліве значення. Якщо це правда, то OR не буде робити подальших перевірок, і відразу поверне істину. Якщо ліве помилкове значення, то OR перевіряє праве значення. В даному випадку, якщо праве значення поверне істину, то й OR поверне істину, в іншому випадку OR поверне брехня.
Оператор NOT (Не) поверне істину тільки в тому випадку, якщо обидва значення повернуть брехня. Фактично, це оператор - перевертиш. Якщо загальне значення буде поправді, він повертає false, а якщо помилково - то істину. Тому дуже часто його використовують в коді, щоб поміняти яке або логічне властивість об'єктів на протилежне, наприклад:
Button1.Enabled := not Button1.Enabled;
Edit1.Visible := not Edit1.Visible;
У цих прикладах береться значення властивостей об'єктів. Якщо це властивість істинно, то оператор not возвращает брехня, і цій властивості присвоюється брехня. І навпаки, якщо властивість помилково, not змушує його прийняти вірне значення. Дуже зручно, коли ви не знаєте заздалегідь, що саме у властивості зберігається, правда чи брехня, але при цьому потрібно присвоїти властивості протилежне значення.
Крім того, оператор NOT часто застосовують у перевірках, якщо потрібно виконати якусь код в тому випадку, якщо умова помилково:
if not Edit1.Text = Label1.Caption then …
Тобто, умова виконується лише в тому випадку, якщо тексти в Edit1 і в Label1 різні. Зверніть увагу, у наведеному прикладі дужок немає. Адже умовна перевірка у нас одна, тому дужок не потрібно, хоча якщо Ви поставите, це теж не буде помилкою. Оператор Not застосовується дуже часто, тому запам'ятайте його.
Перетворення дати
Досі ми ще не стикалися з типом даних Дата. Тим не менш, цей тип дуже широко використовується в програмуванні. В Delphi він називається TDateTime, тобто, возвращает одночасно і дату і час. З-за такий його універсальності часто доводиться застосовувати функції перетворення, щоб повернути тільки дату, або тільки час, причому в різних форматах.
Date()
Ця функція повертає поточні дату і час у форматі TDateTime. Її можна застосовувати з іншими функціями, задаючи їм в якості параметра поточну дату. Приклад:
DateToStr(Date());
DateToStr()
Віддає зазначену у параметрі дату у вигляді рядка. Наприклад,
ShowMessage(DateToStr(Date()));
виведе повідомлення з поточною датою у вигляді рядка. Створіть новий додаток, встановіть форму на кнопку і у обробнику натискання вкажіть цей рядок. Зберіть і подивіться результат.
StrToDate()
Ця функція навпаки, приймає в якості параметра рядок, в якій записали дату в правильному форматі, і повертає цю дату у вигляді TDateTime. Складність полягає в тому, що форматів для надання дати може бути багато. У нас, наприклад, прийнято спочатку вказувати день, потім місяць, і в кінці рік. А американці першим вказують місяць, потім число і рік. Причому рік може бути як 4-х символьними (2007), так і 2-х символьними (07). Ще проблема з роздільниками. Роздільником може служити і крапка (20.09.2007), тире (20-09-2007) або знак слеш (20/09/2007).
Правильну настройку можна побачити у вікні Панель управління - Мова та регіональні стандарти. Крім того, приклад
ShowMessage(DateToStr(Date()));
також поверне вам дату рядком у правильному форматі. Якщо ж ви бажаєте використовувати ці функції для програм на продаж, і не знаєте, які налаштування на комп'ютері покупця, то доведеться використовувати неявні глобальні змінні. Мінлива DateSeparator містить символ - роздільник дат. Порядок проходження дня місяця та року визначається глобальної змінної ShortDateFormat. Можливі наступні комбінації: місяць/день/рік, день/місяць/рік і рік/місяць/день.
Наприклад:
procedure TForm1.Button1Click(Sender: TObject);
begin
DateSeparator := '-'; ShortDateFormat :=
'm/d/yyyy'; Label1.Caption :=
DateToStr(Date); end;
Тут ми не просто дивимося значення DateSeparator і ShortDateFormat, а присвоюємо їм нове значення. Надалі, висновок дат буде здійснюватися вже за новими правилами. Так, для дати 15.09.1994 в властивість Caption компонента Label1 буде записано текст «9-15-1994». Якщо б ми вказали
ShortDateFormat := 'mm/dd/yyyy';
Те, що виводяться, місяць і день були б з нулями, якщо вони менше 10: «09-15-1994»
FormatDateTime()
Ця функція повертає дату і час рядком у вказаному форматі. Дуже цікава функція, найчастіше використовують саме її, щоб вивести рядок потрібного формату. У функції є два параметра, першим вказується формат рядка, в якому потрібно повернути дату. Другий параметр - мінлива типу TDateTime, яку потрібно перетворити в рядок. В якості другого параметра також можна використовувати функцію Date(), якщо потрібно перетворити поточні дату і час. Цю функцію можна порівняти з функцією FloatFormat(), яку ми вивчали в минулій лекції. Найцікавіше в цій функції - формат рядка, або маска. Він може містити наступні символи:
d - показати день, не підставляючи нулі на початку: 1, 2, 12
dd - показати день з підстановкою нулів на початку: 01, 02, 12
ddd - показати день тижня в короткому форматі: Пн, Вт, Ср
dddd - показати повний день тижня: Понеділок, Вівторок, Середа
m - показати місяць без нулів: 1, 2, 10
mm - показати місяць з нулями: 01, 02, 10
mmm - показати коротку назву місяця: Січ, Лют
mmmm - показати повна назва місяць: Січень, Лютий
yy - показати короткий рік: 07, 98, 00
yyyy - показати повний рік: 2007, 1998, 2000
h - показати годинник, не додаючи нулів: 3, 5, 12
hh - показати годинник з нулями: 03, 05, 12
n - хвилини без нулів: 3, 5, 12
nn - хвилини з нулями: 03, 05, 12
s - секунди без нуля попереду: 3, 7, 30
ss - секунди з нулями: 03, 07, 30
Це практично повний набір форматів, які вам можуть знадобитися.
Приклади використання:
ShowMessage('Сегодня '+ FormatDateTime('ddddddmmmyyyyг.', Date)); //Результат: СегодняСреда 06 Фев 2008 г.
ShowMessage('Сегодня ' + FormatDateTime('dd.mm.yyyyг.', Date)); //Результат: Сегодня 06.02.2008 г.
Зверніть увагу, що після функції Date не вказані дужки. Це не помилка. Якщо у функції немає параметрів, її можна вказувати і без дужок.
Час можна вказувати з роздільниками:
ShowMessage('Текущеевремя: '+ FormatDateTime('hh:nn:ss')); //Результат: Текущеевремя: 05:28:15
Компоненти для введення дат
У програмах дуже часто потрібно надати користувачеві можливість ввести дату. Але ми знаємо про проблеми, які можуть виникнути, раптом дати йдуть у форматі mm/dd/yy, а користувач набере 15.08.2008? Вийде помилка. Щоб полегшити користувачеві введення дат, існує кілька компонентів. Створіть новий проект, встановіть на форму компоненти DateTimePicker і MonthCalendar з вкладки Win32 на Панелі компонентів. Зберіть проект і подивіться, як він працює:
|
Рис. 17.1. Зовнішній вигляд програми |
Зверніть увагу на те, як працюють ці календарі. Якщо ви клацніть мишею по номеру року, то відкриється вікно, в якому можна прокрутити до потрібного. Якщо клацніть по місяцю, то відкриється список місяців, в якому користувач може вибрати потрібний. А якщо він лопне з дня, то у властивості Date обох компонентів встановиться дата обрана у форматі TDateTime. Цю дату можна перетворювати у функції перетворення дат в рядок, підставляючи це властивість як значень.
Ще зверніть увагу на нижній рядок. Там вказана поточна дата, а зліва від неї червоний овал. Якщо клацнути по ньому, то обрана дата перескочить з будь-якої дати на поточну.
Ще цікава властивість компоненти: якщо виділити його, вхопитися мишкою за його край і розтягнути, то в збільшеному компоненті поміститься більше, ніж один місяць. Можна розтягнути його так, що поміститься весь поточний рік!
А у компонента DateTimePicker є ще цікава властивість: DateFormat. Воно може показувати дату в короткому або в довгому форматі. Властивість Time цього компонента показує час у форматі TDateTime.
Ці компоненти зручно встановлювати на форму, щоб користувач замість введення потрібної дати просто вибрав її на формі. Крім того, такий підхід забезпечить вам гарантію того, що дата буде вказана в потрібному форматі.
Самостійне завдання
Створіть новий додаток. Встановіть на форму компоненти DateTimePicker, Memo і кнопку, щоб додавати в Memo1 рядка. Спочатку додайте рядок з поточною датою у форматі, прийнятому в російських версіях Windows (функція DateToStr(Date)). Потім додайте пустий рядок, щоб відокремити її від виведених далі форматів. Потім подумайте 10 різних форматів для функції FormatDateTime(),і по черзі додайте їх в Memo1 з тієї датою, яка вказана в DateTimePicker1. До речі, щоб не писати довгі назви, начебто
DateTimePicker1.Date
перейменуйте компонент (властивість Name) у більш коротке ім'я, наприклад, DTP1, тоді звернення вийде коротше:
DTP1.Date
Лекція 18. Збереження параметрів програми
Дуже часто, особливо у великих проектах, буває необхідно зберегти деякі налаштування програми, щоб потім їх застосувати при повторній завантаженні. Уявіть собі таку ситуацію : ви написали програму для клієнта. Він її запустив, і вона з'явилася в центрі вікна, як і планували. Однак йому здалося це незручним, і він обняв її убік і зменшив розмір вікна, щоб паралельно працювати ще з яким то додатком. Всі чудово, програма робить свою справу і користувач задоволений. Однак, коли наступного дня він знову завантажить цю програму, вона знову опиниться в центрі екрана, і буде мати первісні розміри. Користувачеві знову доведеться рухати її убік і зменшувати розміри форми. Дрібничка? Проте з таких ось дрібничок і складається думка про програміста, і якщо думку це буде поганим, замовників у вас не буде! Програміст повинен передбачити в своїй програмі всі вимоги і бажання користувача, навіть такі, про яких він і сам ще не здогадується. Ну скажіть, як користувач, який замовив вам програму може знати, що форма при програмуванні може займати різне положення - по центру екрана або робочого столу, або положення при розробці? Поки він не зіткнеться з вашою програмою на практиці, йому і в голову не прийде вказати вам, що програма повинна запам'ятовувати свої налаштування!
У самому простому випадку потрібно зберегти тільки 5 параметрів - стан вікна (згорнуте, розгорнутий), його положення від лівої і верхньої межі робочого столу, його ширину та висоту. А якщо ви будете створювати більш складну програму, з панеллю налаштувань, де є купа чекбоксів і радіокнопок? Там користувач може змінити ваші налаштування за замовчуванням, і поставити власні. Уявіть, якщо користувач витратив півгодини на те, щоб налаштувати програму «під себе», а при повторному запуску виявив, що всі налаштування не збереглися!
Для збереження налаштувань користувача існує два способи - ini файли і системний реєстр Windows. Кожен з цих методів має свої плюси і мінуси.
Якщо ви зберігаєте налаштування реєстру Windows, то вони приховані від користувача, отже, він нічого не зможе в них зіпсувати. З іншого боку, якщо на комп'ютері зареєстровані кілька користувачів, то кожен зможе змінити налаштування програми «під себе». Мінус в тому, що якщо Windows буде переустановлена, доведеться перевстановити програму, оскільки вона буде відсутній в реєстрі.
Якщо ж ви зберігаєте налаштування ini-файл, програма збереже налаштування і при перевстановлення операційної системи. Крім того, збереження налаштувань в ini файл реалізувати простіше. У цій лекції ми навчимося працювати тільки з ini-файлами.