Побудова строковой бібліотеки в CBuilder

Ми вирішили, що створити бібліотеку (DLL), що містить наші рядкові ресурси, – завдання потрібна, так що пора цим зайнятися Створення DLL в CBuilder не є складним процесом, так само як і створення рядків, входять в цю бібліотеку Отже, поїхали

Створіть у CBuilder новий проект, вибравши команду File д New На сторінці Projects сторінкового діалогу виберіть DLL з доступних типів обєктів Натисніть на кнопку OK, і CBuilder згенерує «скелет» DLL, включаючи весь попередній код Ми не збираємося працювати з цим кодом в даному прикладі, так як ця DLL не міститиме жодного додаткового коду

Створіть новий текстовий файл у CBuilder і додайте в нього наступні рядки Це буде наш строковий ресурс для DLL

STRINGTABLE  DISCARDABLE BEGIN

1001 &quotHello&quot

1002 &quotAloha&quot

1003 &quotShalom&quot

1004 &quotHola&quot END

На випадок, якщо ви не працювали з таблицями рядків раніше: принцип вкрай простий Ресурс

«Таблиця рядків» визначається виразом STRINGTABLE DISCARDABLE Ключове слово STRINGTABLE говорить компілятору ресурсів, що наступні рядки описують ресурс таблиці рядків Прапорець DISCARDABLE вказує, що даний блок не обовязково зберігати у фіксованій області памяті і що при необходимос ти його можна вивантажувати на диск Після визначення блоку йде вираз BEGIN, Яке вказує на початок визначення рядків у таблиці

Кожен рядок у таблиці представлена ​​цілим значенням і символьним значенням Цілі значення потрібні для ідентифікації кожного рядка унікальним номером Коли ви будете посилатися на рядок, використовуючи ідентифікатор ресурсу, вам знадобиться це значення Коли таблиця рядків закінчена (у ній може бути будь-яку кількість елементів), ви закриваєте блок опису таблиці рядків виразом END

Збережіть цей файл як stringsrc в каталозі з вашим проектом в CBuilder Додайте ресурс до проекту, викликавши команду меню Project д Add to Project і вибравши файл stringrc CBuilder знає, що робити з файлами опису ресурсів (resource script, RC), так що більше робити нічого не потрібно Закрийте файл і зберіть проект звичайним чином, вибравши Project д Make або натиснувши F9 Файл ресурсу скомпіліруется, і, якщо не буде знайдено помилок, буде створений файл DLL От і все про побудову DLL в CBuilder

Наступним кроком у нашому прикладі є створення форми, яка б використовувала тільки що створену нами «з таким трудом» DLL У даному прикладі ми хочемо, щоб рядки, що містяться в DLL, представляли собою уявлення статичного тексту у формі на різних мовах Насправді, якщо ви подивитеся на дані, то побачите, що рядки містять слово

«Hello» (привіт) на різних мовах (хоча в даному випадку для них використовується латинський алфавіт)

На рис 101 представлена ​​форма, яку ми будемо використовувати для відображення даних Як бачите, на формі одна мітка статичного тексту і чотири перемикача (radio buttons) Це все, що нам буде потрібно для реалізації даного прикладу

Рис 101 Форма прикладу динамічного завантаження рядків

Після побудови форми потрібно подумати про завантаження даних з DLL Для цього вам доведеться розібратися з двома різними функціями Windows API Ми говорили про Windows API в попередньому розділі, і ці дві функції ще нами не досліджені

Першою функцією API, яку треба вивчити, є функція LoadLibrary вона дозволяє відкривати і брати дані з динамічної бібліотеки (DLL) на диску Для того щоб ми могли використовувати нашу DLL в подальшому коді для форми, нам потрібно відкрити її, коли форма завантажується Так що ми використовуємо конструктор класу форми для ініціалізації посилання (handle) на бібліотеку Додайте наступний код в конструктор форми:

__fastcall TForm1::TForm1(TComponent *Owner)

: TForm(Owner)

{

hLibHandle = LoadLibrary(&quotproject1dll&quot)

}

Крім того, вам потрібно додати опис змінної hLibHandle в заголовний файл форми Додайте цю строчку в секцію private опису класу форми в заголовному файлі:

private: // User declarations HINSTANCE  hLibHandle

Ці дві зміни дають вам повний доступ до вмісту бібліотеки project1dll, яку ми побудували в попередньому розділі Функція LoadLibrary дає вам посилання на екземпляр DLL Чому посилання на екземпляр Тому що бібліотеки DLL можуть бути завантажені одночасно кількома додатками, що працюють в Windows Ось чому вони корисні Якщо десяток різних додатків використовує код або ресурси в DLL, то вони можуть все використовувати спільно одну і ту ж DLL, завантажену в память Коли ви використовуєте функцію API LoadLibrary, Ви збільшуєте лічильник використання DLL Бібліотека DLL буде вивантажено з памяті тільки

тоді, коли всі додатки, що використовують її, будуть вивантажені з памяті (тобто звільнять посилання на бібліотеку)

Завантажуючи бібліотеку функцією LoadLibrary, Не забувайте звільнити її, коли робота закінчена Якщо ви цього не зробите, то вона буде сидіти в памяті, поки Windows не здогадається позбутися її Створіть обробник події форми OnClose і додайте в метод FormClose наступний код:

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &ampAction)

{

if ( hLibHandle = NULL )

{

FreeLibrary( hLibHandle )

}

}

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

Отже, бібліотека завантажена і форма відображена Наступний крок – отримувати рядки при запиті користувача Давайте спочатку опрацюємо перший перемикач (Англійська) Створіть обробник для першого перемикача на формі і додайте в нього наступний код:

void __fastcall TForm1::RadioButton1Click(TObject *Sender)

{

if ( hLibHandle = NULL )

{

char szBuffer[ 256 ] LoadString( hLibHandle, 1001,

szBuffer,

256 / / розмір буфера

)

Label1-&gtCaption = szBuffer

}

}

Оброблювач спочатку перевіряє, чи була завантажена бібліотека, перевіряючи посилання Якщо вона не дорівнює NULL, то метод викликає функцію API LoadString для завантаження даної рядки з DLL Функція API LoadString має наступний синтаксис:

int LoadString( HINSTANCE hInstance, int nResourceID, LPSTR strBuffer, int nSizeOfBuffer)

У нашому випадку посилання на примірник (HINSTANCE) – Це посилання на бібліотеку, яку ми завантажили функцією LoadLibrary Ідентифікатор ресурсу (nResourceID) – це той же ідентифікатор рядка, що ми описали в нашій таблиці рядків у файлі ресурсу Функція LoadString  шукатиме рядок з тим же ID (ідентифікатором), що і заданий Так що,

подивившись в таблицю рядків, описану вище в цьому розділі, ви побачите, що рядок з ID 1001

є англійським словом «Hello»

Параметри szBuffer і 256 – Це буфер, в якому ми хочемо зберігати отриману рядок, і, відповідно, розмір цього буфера Якщо функція LoadString знайде рядок, довшу, ніж розмір буфера, то вона поверне тільки перші 256 байтів рядка і програма не «впаде»

Для обробки інших перемикачів на формі ми просто змінюємо ID рядки, яку хочемо отримати з DLL Ось обробники трьох перемикачів на формі:

void __fastcall TForm1::RadioButton2Click(TObject *Sender)

{

if ( hLibHandle = NULL )

{

char szBuffer[ 256 ] LoadString( hLibHandle, 1002,

szBuffer,

256 / / розмір буфера

)

Label1-&gtCaption = szBuffer

}

}

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

void __fastcall TForm1::RadioButton3Click(TObject *Sender)

{

if ( hLibHandle = NULL )

{

char szBuffer[ 256 ] LoadString( hLibHandle, 1003,

szBuffer,

256 / / розмір буфера

)

Label1-&gtCaption = szBuffer

}

}

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

void __fastcall TForm1::RadioButton4Click(TObject *Sender)

{

if ( hLibHandle = NULL )

{

char szBuffer[ 256 ] LoadString( hLibHandle, 1004,

szBuffer,

256 / / розмір буфера

)

Label1-&gtCaption = szBuffer

}

}

Як бачите, процес однаковий у всіх випадках Насправді ми могли б помістити весь цей код в одну функцію, яка запитує потрібний рядок в DLL і успадковує в цілому весь

процес:

void GetString( int nId, AnsiString &ampstrLang )

{

/ / Спочатку завантажити DLL

HINSTANCE hLibHandle = LoadLibrary(&quotproject1dll&quot) if ( hLibHandle )

{

char szBuffer[ 256 ]

LoadString( hLibHandle, nId, szBuffer, 256 ) strLang = szBuffer

FreeLibrary( hLibHandle )

}

}

Тоді весь попередній код міг би використовувати одну функцію GetString для отримання потрібних даних Зауважте також, що ми використовували обєкт AnsiString для отримання даних, який краще працює з рядками Рядок такого типу (AnsiString) також може бути безпосередньо присвоєна властивості Caption (Заголовок) мітки статичного тексту

Тепер ви опанували завантаженням рядків, що залежать від мови, з DLL Більше нічого сказати про це, хіба що можна помітити, що такий же процес застосуємо і до растрових малюнків (bitmaps), і до піктограм (icons) в ресурсах Якщо у вас на формі є обєкт «растровий малюнок» (TBitmap), То ви можете присвоїти йому малюнок з ресурсу, отримавши посилання типу HBITMAP з файлу ресурсу і потім присвоївши її властивості Handle (Посилання) обєкта TBitmap Це працює чудово з усім, крім меню Давайте розберемося, чому це так

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

*

*