Програмуємо на C++ з допомогою Borland Builder 6.0. Незручні запитання

Вместо рекламы

Россиянин, ты захотел скачать файл ? Или почитать чего интересного ?
Останови свою войну в Украине !

—————————

Реклама від Google



В статті – відповіді на запитання не для форумів.
Чому досі дехто з користувачів використовує старе, недосконале, але працююче середовище розробки програм Borland Builder 6.0 ? Відповіді на це запитання дуже прості:
– немало є старих програм, написаних в BB6, які іноді ще доводиться змінювати, коректувати.
– не завжди потрібен могутній Visual Studio, а до нього ще й обов’язкове використання Framework потрібної версії.
– цей старий програмний пакет Borland Builder колись вже куплений (або взятий просто так), а сучасні програмні пакети для створення програм ще треба купувати (або десь брати просто так).

Але той програміст, який використовує середовище Borland Builder, традиційно наштовхується на деякі незручності чи неясності, і шукає відповіді на багатьох форумах. Деякі відповіді він отримає вже зараз, а стаття, не сумнівайтесь, буде довго розширюватись і доповнюватись.

Проблема 1. Трохи проблематично організувати довгий, безперервний обчислювальний процес із безперервним виводом проміжних результатів.

Хто не вірить, нехай в Borland Builder 6.0 створить простеньку форму, в тілі програми поставить одну мітку і на цю мітку буде виводити багато результатів. Ось і форма:


В цю мітку Label1 буде виводити багато-багато результатів Пишемо в тіло форми Form1 таку простеньку програму:

K01: i1++;  // просто до змінної i1 додали одиницю
    Label1->Caption=IntToStr(i1); // перетворили значення i1
// в символьну форму і висвітили в Label1
    goto K01; // повторюємо цю дію до нескінченності

За задумкою програміста, він мав би при запуску такої програми побачити вікно Form1, в якому з великою швидкістю збільшується “лічильник”, від одиниці і до “нескінченності”. Запустимо цю програму.
Що, нічого нема ?
А звідки візьметься ? Сама форма Form1 з’явиться на екрані лише тоді, коли повністю буде виконана програма в цій формі, а наша програма, як ми бачимо, ніяк не закінчується.
Але швидкий “лічильник” хочемо. Хтось дав простецьку пораду: поставити таймер. Добре, ставимо таймер.


Тепер необхідна дія має виконуватись в тілі таймера, а не в тілі форми Form1. Ось така дія:
K01: i1++;  // просто до змінної i1 додали одиницю
    Label1->Caption=IntToStr(i1); // перетворили значення i1
// в символьну форму і висвітили в Label1
Запустили програму, і справді побачили “лічильник”, який нескінченно збільшується. Результат є, а радості нема, бо лічильник змінюється дуже повільно, через кожну секунду. Адже в нашому лічильнику стоїть за замовчуванням період 1000 мс, тобто одна секунда. Добре, змінимо параметри таймера, поставимо в таймері одну мілісекунду, менше не можемо.
Стало швидше, а радості нема. Нам треба дуже швидко !
Значить освоюємо організацію потоків. Попробую описати потоки без стандартних книжкових фраз.
По-перше, при запуску програми виконується головний обчислювальний потік програми в формі Form1, і він виконується з високим пріоритетом, доки не буде виконаний. Аж тоді зображення головної форми Form1 з’явиться на екрані.
По-друге, якщо ми в своїй програмі запустили таймер, то обчислювальний потік в тілі таймера виконується з високим пріоритетом кожен раз, коли циклічно, із заданим нами періодом, спрацьовує таймер. Виконується програма, написана в тілі таймера.
По-третє, нам дали можливість створювати додаткові потоки із нижчим пріоритетом, і в тих потоках обчислювальний процес може йти “нескінченно” чи хоча б дуже довго, це не загальмує роботу програми в інших блоках і не загальмує саму операційну систему.

Створюємо такий додатковий потік. По головному меню нашого середовища Borland Builder 6.0 переходимо: File->New->Other->(побачили багато графічних елементів)->Thread Object і натискаємо на Thread Object (власне, Thread – це по-англійськи Потік).
Тут бачимо, що наш новий потік треба якось назвати (латинськими буквами), тому назвемо його Potik.


Тепер, натиснувши OK, маємо заготовку для потоку з нижчим пріоритетом. До традиційного блоку Unit1 нам програма Borland Builder створила додатковий блок Unit2, ще й дописала в ньому пояснюючий текст.


Текст корисний для нас, роздивимось його детально. По-перше, нам підказали, де саме треба писати програму для виконання в цьому потоці (там, де Execute() ), по-друге, показали зразок корисної синхронізації потоків, які належать до Unit1 (головний потік) і до Unit2 (наш потік з низьким пріоритетом). В цьому зразку синхронізуючу підпрограму (вибачаюсь, метод) назвали UpdateCaption, але ми назвемо якось інакше, наприклад, Periodychno:
void __fastcall Potik::Periodychno()
{
Form1->Caption = “Що хочемо, виводимо в головній формі Form1”;
}
Метод Periodychno має розміщуватись не в тілі блока Unit1, а в тілі Unit2. Ось остаточні тексти в модулях:
Unit1
TForm1 *Form1;
//———————————————-
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
new Potik(false);//Нічого не робимо, лише запускаємо потік
}
//————————————————-
Unit2
void __fastcall Potik::Execute()
{
    i1=0;
K01: i1++;
    Ryadok=IntToStr(i1); // перетворюємо значення i1
// в символьну форму і виводимо в  Label1
    Synchronize(Periodychno);
    goto K01; // нескінченно повторюємо
}
//———————————————
void __fastcall Potik::Periodychno()
{
Form1->Label1->Caption = Ryadok;
}
Не забудемо ! В тілі Unit1 і в тілі Unit2 мають бути вкладення:
#include “Unit1.h”
#include “Unit2.h”

Зараз запустимо програму. Працює !
Справді працює, і форму можна мишкою пересувати без проблеми, і не гальмує всю операційну систему, але радості нема. Ми безтолково заставили програму з великою швидкістю виводити проміжні значення на форму, а достатньо було би виводити такі чи інші проміжні значення зі швидкістю не більше 10 раз на секунду, все одно наша зорова реакція  досить повільна.
Зробимо по-розумному. Можна викинути начебто корисний метод Periodychno. а змінну Ryadok перенести на головну форму Form1. Тепер тіло потока виглядає так:
{
    i1=0;
K01: i1++;
    Form1->Ryadok=IntToStr(i1); // перетворюємо значення i1
// в символьну форму і виводимо в  Label1
    goto K01; // нескінченно повторюємо
}
А коли ж виводити проміжні значення в мітку Label1 ? Для цього можна в тілі Form1 застосувати знайомий нам таймер. Додали таймер на форму Form1, період таймера ставимо 100 мс,  тобто 10 раз на секунду. Тепер в тілі Form1 написано:
TForm1 *Form1;
    AnsiString Ryadok;
//——————————————
__fastcall TForm1::TForm1(TComponent* Owner)
:    TForm(Owner)
{
new Potik(false);//так рекомендують запускати потік
}
//——————————————–

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Label1->Caption=Ryadok;
}
//——————————————–
А також не забудемо в тілі Unit1.h вказати, що змінна Ryadok має бути доступна з потока:
class TForm1 : public TForm
{
__published: // IDE-managed Components
    TLabel *Label1;
    TTimer *Timer1;
void __fastcall Timer1Timer(TObject *Sender);
private: // User declarations
public: // User declarations
    __fastcall TForm1(TComponent* Owner);
    AnsiString Ryadok;
};
Нормально ! Працює, лише мітка Label1 чомусь моргає при зміні значень. Приберемо ці моргання з допомогою DoubleBuffered=true:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
DoubleBuffered=true;
new Potik(false);// запускаємо потік
}
Ну, тепер зовсім нормально. Ось таке програмне рішення тепер можна застосовувати в будь-яких “повільних і довгих” програмах, де потрібно візуально контролювати довгий обчислювальний процес.

Проблема 2. Не сумнівайтесь, стаття буде розширюватись.

—————————————-

В Україні війна ! Адміністрація сайту допомагає нашим ЗСУ, регулярно донатить на необхідні військові потреби. І ви не забувайте це робити ! Це наша країна, і нам її відстоювати.
Схема мануал телевизора шасси, схему скачать бесплатно, ищу схему модулей, ищу шасси телевизора, схемы телевизоров, мануалы

Залишити відповідь (Leave a Reply)