AnsiString Famille::GetName(int i)

{return FNames[i];

}

Void Famille::SetName(int i,const AnsiString s)

{FNames[i]=s;

}

Int main()

{

Famille C;

C.Names[0]="Steve"; //calls Famille::SetName()

C.Names[1]="Amy";

C.Names[2]="Sarah";

C.Names[3]="Andrew";

for (int i = 0; i <= 3; i++)

{

//calls Famille::GetName()

puts(C.Names[i].c_str()); //вывод на экран

}

}

4.9. Перегрузка AnsiString Famille::GetName(int i) операторов

В С++ не считая перегрузки функций есть возможность перегрузки операторов. Напомним, что перегрузка это не подмена одних параметров на другие, а добавление новых параметров. В этом случае новые характеристики возникают у операторов.

Необходимость в разработке перегруженных опереаторов обычно появляется после сотворения новых типов переменных. К примеру, представьте для себя AnsiString Famille::GetName(int i), что объектами некоторого класса являются геометрические фигуры. Пусть человек, который употребляет эти объекты, из отдельных фигур желает сделать картину. По-существу картина это новенькая фигура, которая является объектом такого же класса, но с другой стороны она является суммой отдельных фигур. Потому естественно перегрузить символ +, т.е. сделать его применимым для AnsiString Famille::GetName(int i) суммирования геометрических фигур. Это позволит создавать картины из готовых частей.

Перегруженная операция представляет собой функцию со особым именованием, в какой описывается переопределение оператора. Необходимость в перегрузке операторов обычно появляется тогда, когда от оператора требуется чтоб он работал с классами также как с числами. К примеру, оператор + можно использовать для AnsiString Famille::GetName(int i) того, чтоб указать, что строчки необходимо соединить вкупе. Разглядим как можно сделать перегрузку операторов.

Пусть @ некий оператор языка, не считая последующих:

.– доступ к элементу класса (точка);

.*- доступ к указателю (точка со зведочкой);

::- разрешение области видимости (двойное двоеточие);

?:- трехместная условная операция, (вопросительный символ с двоеточием, то же самое, что if AnsiString Famille::GetName(int i) - else);

# - указание препроцессору.

Тогда довольно найти функцию с именованием operator@ требуемым числом и типом аргументов, так, чтоб эта функция делала нужные деяния. Другими словами

Тип_результата operator @ (список_параметров)

{

//тело функции

}

Но в этом случае, когда перегрузка делается в классе, т.е. функция-оператор является членом класса перегрузка имеет вид

Тип_результата имя AnsiString Famille::GetName(int i)_класса::operator @ (список_параметров)

{

//тело функции

}

Другими словами перегрузка оператора это построение функции с именованием из особых знаков без передачи аргументов в очевидном виде. Перегрузка осуществляется при помощи кдючевого слова operator. Хотя функцию operator @ (список_параметров) можно использовать как обыденную функцию. Оба метода будут показана в примере, который AnsiString Famille::GetName(int i) мы разглядим чуток позднее.

При перегрузке операторов следует управляться правилом:

- Перегрузка не может изменять старшинство и ассоциативность операций;

- Нельзя изменять число операндов операций;

- операция присваивания = может быть применена с хоть каким классом без очевидной перегрузки.

- По последней мере один аргумент перегруженного оператора должен принадлежать типу который является классом

- Нереально сделать новый оператор. Все AnsiString Famille::GetName(int i), что можно сделать, - это перегузить имеющийся оператор.

- Нельзя изменять значение оператора по отношению к интегрированным типам, т.е int, double, bool, и т.д.

- Функция-операция (т.е. operator @ ) должна быть или членом класса (структуры), или принимать один либо несколько аргументов, имеющих тип класса либо структуры.

Разглядим пример AnsiString Famille::GetName(int i) перегрузки операторов в задачке сложения всеохватывающих чисел. В программке перегружены операторы + и += . При этом показано, что перегрузка вероятна для избранных типов переменных.

//Сложение 2-х всеохватывающих чисел

#include

#include

using namespace std;

struct Complex{double real, imag;}; /* Объявление структуры в

*в какой хранятся вещественная и надуманная части комлексного числа */

//--------------------------------------------------------

//Перегрузка оператора AnsiString Famille::GetName(int i) +

/*объявляем функцию аргументами которой являются адреса 2-х структур типа Complex*/

Complex operator+(Complex &a, Complex &b){

Complex c;

c.real=a.real+b.real;

c.imag=a.imag+b.imag;

return c;}

//--------------------------------------------------------

//Перегрузка унарного оператора += для всеохватывающих чисел

void operator +=(Complex &a, Complex &b){

/*эта запись гласит о том AnsiString Famille::GetName(int i), что если повстречается аннотация a+=b то необходимо сделать последующее */

a.real=a.real+b.real;

a.imag=a.imag+b.imag;

}

//------------------------------------------------------

/* Перегрузка унарного оператора += для реальных чисел

* типа double */

void operator +=(Complex &a, double b){

a.real +=b;

}

//-------------------------------------------------------

//определение функции для вывода всеохватывающих чисел

void showComplex (const Complex &x){

if(x.imag>=0)cout<

else cout<

}

//--------------------------------------------------------

int main(){

Complex x,y,z1,z2;

x.real=20; x.imag=40;

y.real=30; y.imag=50;

SetConsoleOutputCP(1251);

cout<<"1-ое число:"; showComplex(x); //Вывод числа x

cout<<"2-ое число:"; showComplex(y); //Вывод числа y

z1=operator+(x,y); //тут перегрузка употребляется как функция

cout<<"Определение суммы AnsiString Famille::GetName(int i) при помощи функции:"; showComplex(z1);

z2=x+y; //перегруженный оператор употребляется в операции

cout<<"Определение суммы с помошью оператора:"; showComplex(z2);

z1 +=x; //то же, что operator+=(z1,x);

cout<<"Если добавить 1-ое число к сумме, то получится:"; showComplex(z1);

z2 +=30.0; //то же, что operator+=(z2,30.0);

cout<<"Если добавить число 30 к сумме, то получится:"; showComplex(z AnsiString Famille::GetName(int i)2);

int i; cin>>i;

return 0;

}

Вот итог работы программки

В этой программке одна и таже функция перегрузки

Complex operator+(const Complex &a,const Complex &b)

употребляется по-разному. Один раз как рядовая функция, которая вызывается из функции main() при помощи ее имени с указанием аргументов

z1=operator+(x,y);

2-ой AnsiString Famille::GetName(int i) раз как перегруженный оператор

z2=x+y;

Вызов функции в качестве оператора сложения не вызывает никаких проблем. Напротив, 2-ой вариант, возможно, не совершенно понятен. Создадим некие пояснения. Встретив символ + для небазового типа Complex компилятор инспектирует, не является ли этот оператор перегруженным. С этой целью он отыскивает функцию, у которой AnsiString Famille::GetName(int i) имя содержит ключевое слово operator и обозначенный символ операции. Если эта функция найдена, то он инспектирует соответствие её характеристик числу и типам операндов. После чего обеспечивает выполнение написанного кода.

В качестве примера перегрузки в классе разглядим перегрузку опрератора массива либо, лучше сказать, оператора работы с индексами [ ]. В качестве примера разглядим класс созданный AnsiString Famille::GetName(int i) для хранения строчки и числа. Чтоб привлечь ваше внимание пусть это будет имя шпиона и его поядковый идентификационный номер (ПИН). Программка подготовлена для варианта когда агент по имени Bond запамятовал собственный номер. Введя свое имя, а поточнее фамилию он выяснит номер.

#include

#include

using namespace std;

const AnsiString Famille::GetName(int i) int MAX_LEN=100;

/* Класс для хранения имени шпиона и его ПИНа

* имя хранится в массиве strcpy, а ПИН в переменной типа

* int decoderKey */

class SecretInfo{

int decoderKey;

char codeName[MAX_LEN];

public:

SecretInfo(char *spyName, int spyKey); /*Объявляем конструктор

* с 2-мя аргументами */

int operator [](const char *spyName); //Перегрузка [] вклассе

}; //Конец класса

//Определение конструктора

/* Данный конструктор производит AnsiString Famille::GetName(int i) перезапись аргументов

* в переменные объявленные в классе */

SecretInfo::SecretInfo(char *spyName, int spyKey){

strcpy(codeName, spyName); /* интегрированная функция strcpy

* копирует вторую строчку в первую */

decoderKey=spyKey;

}

/* Определение перегружаемого оператора */

int SecretInfo::operator[](const char *spyName){

if(!strcmp(codeName, spyName)) /* strcmp функция сопоставления строк

* возвращает 0 если строчки совпадают

* следует напомнить, что в языке AnsiString Famille::GetName(int i) С

* заместо false употребляется ноль*/

return decoderKey;

else

return 0;

} //конец функции-оператора

/*сейчас оператор [] значит ПИН агента*/

//===========================================

int main(void){

SecretInfo agent("Bond",7);

char temp[MAX_LEN];

cout<<"Input Your code name:";

cin>>temp;

if(agent[temp])

cout<<"Your Kode Name"<

else

cout<<"Sorry Bond! False Name Code"<

char z AnsiString Famille::GetName(int i);

cin>>z;

return 0;

}

Пример

#include

#include

#include

#include

#define EOS -1 //Конец строчки(возвращаеться функцией get_word)

using namespace std;

class dict_el{ //Элемент словаря (слово и его позиции)

public:

dict_el():Word(""){}; //Конструсторы

dict_el(string wd):Word(wd){};

~dict_el(){}; //Деструктор

void add_pos(const int i){ //Добавить позицию

this->pos.push_back(i AnsiString Famille::GetName(int i));

};

bool operator==(const string& str){

/* сопоставление со строчкой для метода find */

return (this->Word == str)? true:false;

}

friend ostream& operator<<(ostream& cout, dict_el& rhs);

/*Вывод слова и его позиций */

private:

string Word; //Хранимое слово

vector pos; //Позиции для хранимого слова

};

ostream& operator<<(ostream& cout, dict_el& rhs){

/*Вывод слова и его позиций*/

cout AnsiString Famille::GetName(int i) << rhs.Word << ": ";

vector::iterator i;

for (i = rhs.pos.begin(); i != rhs.pos.end(); ++i)

cout << *i << " "; //Выводит слово : и его позиции

return cout;

}

int get_word(string& str,string& res){ //получить последующее слово

static int current=0; //текущая позиция

int i;

while(isspace(str[current]) ) {

++current; //пропустить все знаки AnsiString Famille::GetName(int i) пробел,

} //переход строчки и т.д.

if (str[current] == '\0') return EOS; //достигнут конец строчки

i = current; //начало нового слова

res="";

while(!isspace(str[current]) && str[current] != '\0'){//считывать слово до конца

res+=tolower(str[current++]); //и записывать его в res

}

return i; //возвратить позицию слова

}

void parse_str(string& str, vector& dict){

/* Разбор строчки и формирование AnsiString Famille::GetName(int i) словаря */

string temp; //последующее слово

int position; // и его позиция

vector::iterator i;

while((position=get_word(str,temp)) != EOS){ /*Пока не дошли до конца строчки получить последующее слово */

i=find(dict.begin(),dict.end(),temp); //находить это слово в словаре

if (i == dict.end()){ //если такового слова нет

dict_el A(temp AnsiString Famille::GetName(int i)); //сделать его

A.add_pos(position); //ввести первую позицию

dict.push_back(A); //и добать в словарь

}

else{ //если слово уже есть

(*i).add_pos(position); //добавть к нему новейшую позицию

}

}

}

//Начало программки
int main(){
string str="Testing my Testing my program\0"; //Строчка для разбора

vector dict; //Словарь

parse_str(str,dict); //Сделать словарь

vector::iterator i;

for AnsiString Famille::GetName(int i)(i = dict.begin(); i != dict.end(); ++i){ //Вывести словарь

cout << *i << endl;

}

return 0;

}

Внедрение "умных" указателей

Принципы использования "умных" указателей известны каждому программеру на C++. Мысль максимально ординарна: заместо того, что бы воспользоваться объектами некого класса, указателями на эти объекты либо ссылками, определяется новый тип для которого переопределен селектор ->, что позволяет AnsiString Famille::GetName(int i) использовать объекты такового типа в качестве ссылок на реальные объекты. На всякий случай, приведу последующий пример:

class A {
public: void method();
}

class APtr {
protected: A* a;
public: APtr();
~APtr();
A* operator->();
};

inline APtr::APtr() : a(new A) { }
inline APtr::~APtr() { delete a; }
inline A* APtr::operator->() { return a; }

Сейчас для AnsiString Famille::GetName(int i) объекта, определенного как APtr aptr; можно использовать последующую форму доступа к члену a:

aptr->method();

Тонкости того, почему operator->() возвращает конкретно указатель A* (у которого есть собственный селектор), а не, к примеру, ссылку A& и все равно все компилируется таким макаром, что выполнение доходит до способа A::method(), я AnsiString Famille::GetName(int i) пропущу за ненадобностью --- я не собираюсь говорить о том, как работает этот механизм и какие приемы используются при его использовании --- это очень тщательно написано в книжке Джеффа Элджера "C++ for real programmers" (комментарий к этой восхитительной книжке непременно появится в соответственном разделе моей страницы), в какой вообщем практически половина AnsiString Famille::GetName(int i) книжки посвящена "умным" указателям.

Достоинства такового подхода, в принципе, явны: возникает возможность контроля за доступом к объектам; незначительно обычных телодвижений и выходит указатель, который сам считает количество применяемых ссылок и при обнулении автоматом уничтожает собственный объект, что позволяет не хлопотать об этом без помощи других... не принципиально AnsiString Famille::GetName(int i)? Почему же: самые тяжело отлавливаемые ошибки это ошибки в использовании динамически выделенных объектов. Сплошь и рядом можно повстречать: попытка использования указателя на удаленный объект, двойное удаление объекта по одному и тому же адресу, неудаление объекта. При всем этом последняя ошибка, в принципе, самая безопасная: программка, в какой не удаляются AnsiString Famille::GetName(int i) объекты (как следует, пропадает память, которая могла бы быть применена повторно) может полностью тихо работать в течение некого времени (при этом это время может тихо колебаться от нескольких часов до нескольких дней), чего полностью хватает для решения неких задач. При всем этом увидеть такую ошибку довольно легко: довольно следить динамику использования AnsiString Famille::GetName(int i) памяти программкой; не считая того, есть особые средства для отслеживания схожих казусов, к примеру BoundsChecker.

1-ая ошибка в этом перечне тоже, в принципе, довольно обычная: внедрение после удаления вероятнее всего приведет к тому, что операционная система произнесет соответственное системное сообщение. Ужаснее становится тогда, когда подобного сообщения не возникает (т AnsiString Famille::GetName(int i).е., данные довольно правдоподобны либо область памяти уже занята чем-либо другим), тогда программка может повести себя каким угодно образом.

2-ая ошибка может дать самое огромное количество проблем. Все дело в том, что, хотя на 1-ый взор она ничем особым не отличается от первой, все же на практике AnsiString Famille::GetName(int i) повторное удаление объекта приводит к тому, что менеджер кучи удаляет что-то совершенно немыслимое. Вообщем, что означает "удаляет"? Это означает, что отмечает память как пустую (готовую к использованию). Обычно, менеджер кучи, для того что бы знать, сколько памяти удалить, в блок выделяемой памяти вставляет его размер. Итак вот, если AnsiString Famille::GetName(int i) память уже была занята кое-чем другим, то по "неправильному" указателю находится неверное значение размера блока, таким макаром менеджер кучи удалит некий случайный размер применяемой памяти. Это даст последующее: при последующих выделениях памяти (в какой-то момент) менеджер кучи даст эту "неиспользуемую" память под другой запрос и... на AnsiString Famille::GetName(int i) одном клоке места будут ютиться два различных объекта. Крах программки произойдет практически непременно, это наилучшее что может случится. Существенно ужаснее, если программка остается работать и будет выдавать правдоподобные результаты. Одна из самых уникальных ошибок, с которой я столкнулся и которая, вероятнее всего, была вызвана конкретно повторным удалением 1-го и такого AnsiString Famille::GetName(int i) же указателя, было то, что программка, работающая несколько часов, в какой-то момент "падала" в... функции malloc(). При этом проработать она должна была конкретно несколько часов, по другому эта ситуация не повторялась.

Таким макаром, автоматическое удаление при гарантированном неиспользовании указателя, это очевидный плюс. В принципе, можно позавидовать программерам на Java AnsiString Famille::GetName(int i), у каких схожих заморочек не появляется; зато, у их появляются другие трудности ;)

Я еще не уверил вас в полезности использования "умных" указателей? Удивительно. Тогда я приведу примеры реального использования в собственных проектах. Вот, к примеру, объявление того самого "умного" указателя с подсчетом ссылок, о котором я гласил AnsiString Famille::GetName(int i):

template

Class MPtr

{

public:

MPtr();

MPtr(const MPtr& p);

~MPtr();

MPtr(T* p);

T* operator->() const;

operator T*() const;

MPtr& operator=(const MPtr& p);

protected:

Struct RealPtr

{

T* pointer;

unsigned int count;

RealPtr(T* p = 0);

~RealPtr();

};

RealPtr* pointer;

private:

};

4.8. Полиморфизм

Полиморфизм это очередное увлекательное свойство классов. В более общем осознании полиморфизм значит способность с одним именованием AnsiString Famille::GetName(int i) функции несколько ее реализаций. Мы уже сталкивались с перегрузкой имен, которая является личным случаем полиморфизма. Не считая того только-только у нас были два класса с схожими именами. По другому говоря неприметно себе мы уже познакомились с этим свойством, но сейчас разглядим более пристально все способности которые AnsiString Famille::GetName(int i) оно открывает.

Время от времени создавая код программер пытаясь сделать некоторый универсальный продукт попадает в ситуацию связанную с неопределенностью. К примеру, мы собираемся написать программку для учета всех продаж магазина. Казалось бы чего проще. Трудность заносит то событие, что типов продаж может быть достаточно много. Не считая обыденных продаж по обозначенной стоимости AnsiString Famille::GetName(int i) могут быть реализации со скидкой, реализации с доставкой на дом посыльным, реализации по почте. Спустя какое то время потребуются еще некие типы продаж, к примеру, выигрыши по лотереи и т.п. Каждому типу реализации соответствует собственный вид счета. К концу какого-нибудь отчетного периода, к примеру AnsiString Famille::GetName(int i), к концу денька, на основании выписанных счетов, нужно вычислить общий объем продаж, среднюю величину реализации, также наименьшую и наивысшую величину реализации.

Главное меню — компонент MainMenu

Компонент Главное меню - MainMenu– размещен на закладке Standard.

Это невизуальный компонент. Это означает, что его размещение на форме не играет никакого значения, его можно расположить в AnsiString Famille::GetName(int i) любом месте формы.

Основное свойство компонента — Items. Его можно отыскать в окне Инспектора Объектов.

После щелчка по полю (Menu) появится кнопка с многоточием. Нажатие этой кнопки (либо двойной щелчок по пиктограмме компонента на форме) вызывает возникновение окна

Конструктор меню Инспектор объектов

которое является моделью, либо конструктором меню. Сразу в инспекторе Объектов появится новый объект AnsiString Famille::GetName(int i) без имени с открытым окном Caption. В окно следует внести имя меню, к примеру Файл. Если сейчас надавить кнопку Enter, то это имя появится в конструкторе меню, а в Инспекторе объектов появится имя N1 и бледноватый текст подсказки TMenuItem

Конструктор меню Инспектор объектов

Не считая того, в конструкторе меню, появится место AnsiString Famille::GetName(int i) для сотворения нового раздела, которое выделено рамкой из точек. Щелчок по этой рамке приведет кпоявлению новонго безымянного раздела меню. Если будет нужно разделы меню поменять местами, то это можно сделать перетащив его на необходимое место при помощи мыши.

Щелчок по имени сделанного раздела приводит к возникновению рамки для сотворения пт AnsiString Famille::GetName(int i) меню и к возникновению нового безымянного объекта в инспекторе объектов. Создание пт меню ничем не отличается от сотворения разделов. Пункты меню можно перетаскивать.

Если будет нужно поместить новый пункт меню меж уже сделанными пт то это можно сделать при помощи контекстного меню, которое возникает после щелчка правой кнопкой мыши AnsiString Famille::GetName(int i). Щелчок по Insert добавляет новый пункт, соответственно щелчок по Delete удаляет его. Если это не выходит, то снова воспользуйтесь свойством Items.

Контекстное меню для сотворения нового пт Меню после щелчка по Insert

Принципиальной командой является CreateSubmenu, которая позволяет сделать подменю. Но для этого еужно поначалу установить свойство Default равным true.

Описание главных параметров приведено ниже.

Свойство AnsiString Famille::GetName(int i) Описание
Caption Определяет надпись раздела. Знак амперсанд позволяет обозначить кнопок резвого доступа. Если ввести знак минус "-", то заместо раздела в меню появится разделитель в виде черты
Shortcut Определяет кнопки резвого доступа к разделу меню жаркие кнопки, при помощи которых юзер, не заходя в меню, может в AnsiString Famille::GetName(int i) хоть какой момент вызвать выполнение процедуры, связанной с данным разделом. Чтоб найти кнопки резвого доступа, нужно открыть выпадающий списоксвойства Shortcut в окне Инспектора Объектов и избрать из него подходящую комбинацию кнопок.
Name Определяет имя объекта, соответственного разделу меню. Рекомендуется давать объектам осмысленные имена. Имена в виде номера стремительно приводят AnsiString Famille::GetName(int i) к неурядице.
Default Показывает, имеет ли данный пункт по дефлоту свое подменю. умолчанию, выделяемый жирным шрифтом
Break Употребляется в длинноватых меню, чтоб разбить перечень разделов на несколько столбцов. Вероятные значение Break: mbNone — отсутствие разбиения меню (это значение принято по дефлоту), mbBarBreak и mbBreak - в меню вводится новый столбец разделов, отделенный от предшествующего AnsiString Famille::GetName(int i) полосой (mbBarBreak) либо пробелами (mbBreak).
Checked показывает, что в разделе меню будет отображаться маркер флага, показывающий, что данный раздел избран
AutoCheck Если его установить в true, то при каждом выборе юзером данного раздела маркер будет автоматом переключаться,указывая то на выбранное.состояние, то на отсутствие выбора AnsiString Famille::GetName(int i)
Radioltem true значит, что данный раздел должен работать в режиме радиокнопки вместе с другими разделами, имеющими то же значение характеристики Grouplndex. По дефлоту значение GroupIndex равно 0.
Enabled Значит доступносить.Еслиfalse,то будет изображаться сероватая надпись и пункт меню не будет реагировать на щелчок юзера
Visible Видимость. Употребляются для конфигурации AnsiString Famille::GetName(int i) состава доступных юзеру разделов.
Bitmap Позволяет ввести изображение в раздел, выбрав его из обозначенного файла
Imagelndex Позволяет указать индекс изображения, лежащего во наружном компоненте ImageList

Основное событие раздела — OnClick,возникающее при щелчке юзера на разделе либо при нажатии «горячих№ кнопок резвого доступа.

Свойство — Action..

Сославшись на ранее описанное действие, вы AnsiString Famille::GetName(int i) избавляетесь от необходимости задавать большая часть из обозначенных выше параметров, потому что они наследуются от объекта деяния. Вам не требуется также писать обработчик действия OnClick,потому что он оже наследуется от деяния.

Диалоги

В приложениях нередко приходится делать деяния связанные с выбором и доказательством либо отрицаемем неких действий. К примеру, необходимо AnsiString Famille::GetName(int i) избрать файл из предлагаемрго перечня. Для этого употребляются составляющие, размещенные на вкладке Dialogs. Но не всегда нас могут устроить стандартные диалоги. Невзирая на то, что в их предусмотрены довольно широкие способности опции, специфичность наших приложений может добиваться каких-либо дополнительных функций, которые нереально воплотить в стандартном диалоге. Потому AnsiString Famille::GetName(int i) в C++Builder имеются составляющие, которые можно рассматривать как куски диалоговых окон. Из их можно создавать собственные диалоги.

Пиктограмма Компонент Описание
OpenDialog Делает окно типа «Открыть файл»
SaveDialog Делает окно типа «Сохранить файл»
OpenPictureDialog Делает окно типа «Открыть рисунок»
SavePictureDialog Делает окно типа «Сохранить рисунок»
FontDialog Делает окно AnsiString Famille::GetName(int i) типа «Выбрать шрифт»
ColorDialog Делает окно типа «Выбрать цвет»
PrintDialog Делает окно типа «Печать»
PrinterSetupDialog Делает окно типа «Установка принтера»
FindDialog Делает окно типа «Найти»
ReplaceDialog Делает окно типа «Заменить»

На вкладке Additional еще есть два диалога

Пиктограмма Компонент Описание
ColorBox Делает перечень для выбора цвета
CustomizeDlg Делает настраиваемый диалог, связанный со AnsiString Famille::GetName(int i) стандартными действиями.

Еще есть несколько диалогов исполненных в стилеWindows 3.1, но в текущее время они фактически не употребляются.

Все характеристики этих компонент схожи. Основное свойство, в каком ворачивается в виде строчки избранный юзером файл, — FileName.Значение этогосвойства можно задать и перед воззванием к диалогу. Тогда оно появится в диалоге как AnsiString Famille::GetName(int i) значение по дефлоту в окне Название файла.

Все диалоги являются невизуальными компонентами, так что место их размещения на форме не имеет значения. При воззвании к этим компонентам вызываются стандартные диалоги, вид которых находится в зависимости от версии Windows и опции системы. Так что при запуске 1-го и такого же приложения AnsiString Famille::GetName(int i) на компьютерах с различными системами диалоги будут смотреться по-разному. К примеру, при русифицированной версии Windows все их надписи будут русскими, а при английской версии надписи будут на британском языке.

В качестве иллюстрации неких способностей диалоговых компонент сделаем форму, в какой меню позволяет вызвать некие диалоги. Для этого поместим AnsiString Famille::GetName(int i) на форму составляющие Edit, MainMenu, OpenDialogиSaveDialog.

Сделаем обычное меню

Чтоб избежать неурядицы в числовых именах разделовтменю их следует переименовать. В предстоящем это будут File, Open, Save, Exit.

В модуле формы сделаем глобальную переменную

AnsiString MyFileName="";

Обработчик OnClick раздела Открыть запишем так:

void __fastcall TForm1::OpenClick(TObject *Sender)

{

if(OpenDialog1->Execute()){

MyFileName=OpenDialog AnsiString Famille::GetName(int i)1->FileName;

Edit1->Text=MyFileName;

}

}

Поясним этот код.

Основной способ, которым делается воззвание к хоть какому диалогу, -Execute.Эта функция открывает диалоговое окно и, если юзер произвел в нем некий выбор, то функция возвращает true.При всем этом в свойствах компонента — диалога запоминается выбор юзера, который можно прочесть и использовать в последующих AnsiString Famille::GetName(int i) операциях. Если юзер в диалоге надавил кнопку Отмена либо кнопку Esc, то функция Executeвозвращает false.Потому стандартное воззвание к диалогу имеет вид:

if ( -> Execute())

;

Нередко требуется выводит в диалог не все файлы, а только те, которые имеют данное расширение, к примеру, exe, doc, txt. Для этого существует окно «Тип файлов».

Типы разыскиваемых AnsiString Famille::GetName(int i) файлов, появляющиеся в диалоге в выпадающем перечне. Тип файла задаются свойством Filter.Для этого щелчком по установленному на форме компоненту, в этом случае это OpenDialog, выделитьнужный компонет. В Инспекторе Объектов щелкнуть по окошку Filtr, и надавить показавшуюся кнопку с многоточием.

После чего раскрывается окно редактора с таблицей из 2-ух колонок. В AnsiString Famille::GetName(int i) левую половину записывается описание файлов, т.е. текст который увидит юзер в выпадающем перечне, а в правую, через точку с запятой, их расширения.

В этом случае задано три фильтра:

◦ фильтр текстовых файлов с расширениями .doc, .txt,.rtf,

◦ фильтр исполняемых файлов с расширениями .exe, .com,

◦ всех файлов с шаблоном AnsiString Famille::GetName(int i) "*.*".

После выхода из окна редактирования фильтров данные шаблоны появятся в свойстве Filterв виде строчки вида:

Текст (doc, txt, rtf)|*.doc; *.txt; *.rtf|Исполняемые|*exe; *.com|Все файлы|*.*

В этой строке тексты и шаблоны делятся вертикальными линиями. В аналогичном виде, если требуется, можно задавать свойство Filterпрограммно во время выполнения приложения AnsiString Famille::GetName(int i).

Свойство Описание
Filterlndex определяет номер фильтра, который будет по дефлоту показан юзеру в момент открытия диалога. К примеру, значение FilterIndex=1 задает по дефлоту 1-ый фильтр.
InitialDir определяет исходный каталог, который будет открыт в момент начала работы юзера с диалогом. Если значение этого характеристики не задано, то раскрывается текущий каталог либо тот AnsiString Famille::GetName(int i), который был открыт при последнем воззвании юзера к соответственному диалогу в процессе выполнения данного приложения.
DefaultExt определяет значение расширения файла по дефлоту. Если значение этого характеристики не задано, юзер должен указать в диалоге полное название файла с расширением. Если же задать значение DefaultExt,то юзер может писать в диалоге имя AnsiString Famille::GetName(int i) без расширения. В данном случае будет принято данное расширение.
Title позволяет задать заголовок диалогового окна. Если это свойство не задано, окно раскрывается с заголовком, определенным в системе (к примеру, ≪Сохранить как≫). Но можно задать и собственный заголовок, подсказывающий юзеру ожидаемые деяния. К примеру, ≪Укажите имя и тип AnsiString Famille::GetName(int i) сохраняемого файла
Options определяет условия выбора файла.

Огромное количество опций, которые можно установить программно либо во время проектирования, включает:

ofAllowMuItiSelect Позволяет юзеру выбирать несколько файлов.
ofCreatePrompt В случае, если юзер написал имя несуществующего файла, возникает замечание и запрос, нужно ли сделать файл с данным именованием.
ofEnablelncludeNotify Разрешает посылать в диалог AnsiString Famille::GetName(int i) сообщения.
ofEnableSizing Разрешает изменять размер окна
ofExtensionDifferent Этот флаг, который можно прочесть после выполнения диалога, указывает, что расширение файла, избранного юзером, отличается от DefaultExt.
ofFileMustExist В случае, если юзер написал имя несуществующего файла, возникает сообщение об ошибке.
ofРideReadOnly Удаляет из диалога индикатор Открыть только для чтения.
ofNoChangeDir После щелчка AnsiString Famille::GetName(int i) юзера на кнопке ОК восстанавливает текущий каталог, независимо от того, какой каталог был открыть при поиске файла.
ofNoDereferenceLinks Воспрещает переназначать кнопки резвого доступа в диалоговом окне.
ofNoLongNames Показываются только менее 8 знаков имени и 3-х знаков расширения.
ofNoNetworkButton Убирает из диалогового окна кнопку поиска в сети. Действует только AnsiString Famille::GetName(int i) если флаг ofOldStyleDialog включен.
ofNoReadOnlyReturn Если юзер избрал файл только для чтения, то генерируется сообщение об ошибке.
ofNoTestFileCreate Воспрещает выбор в сети защищенных файлов и труднодоступных дисков при сохранении файла.
ofNoValidate Не позволяет писать в именах файловнеразрешенные знаки, но не мешает выбирать файлы с неразрешенными знаками.
ofOldStyleDialog Делает диалог выбора файла AnsiString Famille::GetName(int i) в древнем стиле
ofOverwritePrompt В случае, если при сохранении файла юзер написал имя имеющегося файла, возникает замечание, что файл с таким именованием существует, и запрашивается желание юзера переписать имеющийся файл.
ofPathMustExist Генерирует сообщение об ошибке, если юзер указал в названии файла несуществующий каталог.
ofReadOnly По дефлоту включает индикатор Открыть только AnsiString Famille::GetName(int i) для чтения при открытии диалога.
ofShareAware Игнорирует ошибки нарушения критерий коллективного доступа и разрешает, невзирая на их, создавать выбор файла.
ofShowHelp Показывает в диалоговом окне кнопку Справка.

В компонентах диалогов открытия и сохранения файлов предусмотрена возможность обработки ряда событий. Такая обработка может потребоваться, если рассмотренных опций AnsiString Famille::GetName(int i), невзирая на их количество, не хватает, чтоб установить все диктуемые определенным приложением ограничения на выбор файлов. Событие OnCanCloseпоявляется при обычном закрытии юзером диалогового окна после выбора файла. При отказе юзера от диалога — нажатии кнопки Отмена, кнопки Esc и т.д. событие OnCanCloseне наступает. В обработке действия OnCanCloseможно произвести дополнительные AnsiString Famille::GetName(int i) проверки избранного юзером файла и, если по условиям вашей задачки этот выбор недопустим, можно известить об этом юзера и задать значение falseпередаваемому в обработчик параметру CanClose.Это не позволит юзеру закрыть диалоговое окно.

Можно также написать обработчики событий OnFolderChange— изменение каталога, OnSelectionChange— изменение названии файла, OnTypeChange— изменение типа файла. В этих обработчиках вы сможете предугадать AnsiString Famille::GetName(int i) какие-то сообщения юзеру.

Файлы и потоки

В языке С++ операторов ввода-вывода нет. Потому для передачи данных с 1-го устройства на другое употребляются, так именуемые, потоки. В программировании слово поток перегружено смысловыми значениями. В этом случае слово поток это вспомогательная программка (объект класса), которая обеспечивает направленное движение данных. Хотя нередко AnsiString Famille::GetName(int i) под потоком понимают само побайтное перемещениедвижение данных. Такое двусмысленное значение слова поток, обычно, не вызывает противоречий.

Если движение данных ориентировано в программку, то поток именуют входным потоком, если из программки то выходным потоком. Кстати говоря, использованные нами «операторы» cin и cout организуют соответственно входной и выходной потоки. При этом cin (console input AnsiString Famille::GetName(int i)) это входной поток с клавиатуры, поточнее стандартный поток ввода операционной системы, а cout (cosole output) это выходной поток данных на экран либо стандартный поток вывода операционной системы. Директива #include позволяет получить доступ к библиотеке программ, которая автоматом делает эти потоки. Кстати говоря, стандартные потоки могут быть перенаправлены на другие AnsiString Famille::GetName(int i) устройства либо в файлы.


antichnaya-etika-sokrat-epikur-i-stoiki.html
antichnaya-filosofiya-dosokratiki-i-sokrat.html
antichnaya-filosofiya-kosmologizm.html