Отправляет email-рассылки с помощью сервиса Sendsay

Delphi - проблемы и решения

  Все выпуски  

Проблемы и решения в Delphi #22


Служба Рассылок Subscribe.Ru проекта Citycat.Ru

Проблемы и решения в Delphi - выпуск 22 от 13.07.2001.


Ученым свет, а остальным
полумрак кабаков........


ВСЕ ВОПРОСЫ СПРОСИТЬ ПРЕДЛОЖИТЬ АРХИВЫ СКОЛЬКО НАС


Доброго Вам времени суток уважаемый читатель.

Сегодня в выпуске :
~~~~~~~~~~~~~~~~~~~
1. Меню в Delphi.
2. Ищу подельника.
3. Очередные вопросы.
4. Отвеченные вопросы.
~~~~~~~~~~~~~~~~~~~


1. Меню в Delphi.
-----------------
Кто не знает, что такое меню? Мне кажется, что среди читателей рассылки
таких уж нет точно. Особая разновидность меню - это всплывающие.
В Delphi для них есть два различных меню: 'MainMenu' и 'PopupMenu',
соответственно локальное и всплывающее. Немного о стадии их визуальной
разработки. Все до безобразия просто - кладем компонент на форму и дважды
по ней щелкая получаем заготовочку, где прямо мышкой создаем нужную
структуру меню и все. Теперь осталось только обрабатывать созданные пункты
и подпункты меню. Как? Не смешите - все то же событие OnClick.

Для PopupMenu есть небольшой ньюанс. Нужно привязать его к тому на чем
собственно будет всплывать это меню(по умолчанию, нужно щелкнуть правой
кнопочкой мышки в этом месте). У различных компонентов, например тот же
фрейм,есть свойство PopupMenu где нужно указать какое из созданных меню
будет всплывать при вызове(ведь таких можно наделать сколько хочешь и
разным компонентам подвесить свое).

Гораздо интереснее создавать меню во время выполнения программы. Собственно
для создания любой компоненты служит ее метод 'Create', например
...
var Menu: TMenuItem;

NMenu:= TMenuItem.Create(Self);
...

Т.е. тоже вроде не сложно. Далее заполняете Caption и все, что еще нужно.
Вопрос в том, как же теперь(т.е. в момент выполнения программы) заставить
по щелчку на нашем меню что либо сделать. Т.е. как нам добраться до заветного
OnClick. Вот немного подробнее.

type
...
procedure MenuProgram(Sender: TObject); // Наша процедурка
...

А для меню указываете: Nmenu.Items[Nom].OnClick := MenuProgram;
где Nom - номер элемента меню.


2. Ищу подельника.
------------------
Я сам сейчас разбираюсь с Делфями, но тупо ковыряя очень тяжело
добиться каких либо результатов. Хотелось бы найти какого нибудь
компаньёна который мог бы предложить написать что нибудь совмесное,
а я буду стараться оказать посильную помощь.
Мой mail: nks13@ukrpost.net .


3. Очередные вопросы.
---------------------


Вопрос 350:

От: Shaman

Господа, кто-нибудь знает, где можно достать доки, где Internet
Explorer описан как СОМ объект. В общем, мне нужно написать клиент
автоматизации для IE.


Ответить.

Ответ 1:


Вопрос 351:

От: Bikkin Marat

Уважаемые господа программисты, у меня к Вам два вопроса по теме
DBE/Database Desktop.

1. Как посмотреть какие VALIDITY CHECKS были навешаны на поля
базы ? (хочу сделать restructure в Database Desktop а он говорит
"maximum validity checks failed
field: size " :(.

2. Как изменить эти самые validity checks --правила "занесения"
информации в поля базы и как там вообще могла оказаться
информация, неправильная с точки зрения этих правил?


Ответить.

Ответ 1:


Вопрос 352:

От: Олег Гончаренко

Сделал прогу на подобии winpopup. Использовал
компоненты TNMMsg TNMMsgServ. Работает четко,
но как при запуске проги проверить, кто из
собеседников уже есть и занести их в combobox
или другой список?????
второе как передать собеседнику с помощью этих
компонент файл, думаю надо использовать поток,
но как????

procedure TForm1.NMMsg1MessageSent(Sender: TObject);
begin
StatusBar1.Panels[1].Text := 'Сообщение ' + NMMsg1.Host + '
отправлено!';
end;

//прием сообщения
procedure TForm1.NMMSGServ1MSG(Sender: TComponent; const sFrom,
sMsg: String);
begin
//восстанавливаю окно
if WindowState = wsMinimized then
begin
WindowState := wsNormal;
ShowWindow(Form1.Handle, SW_RESTORE);
end;
StatusBar1.Panels[1].Text := 'Сообщение от '+sFrom;
//подаю сигнал
MediaPlayer1.Play;
Memo1.Lines.Add('['+ sFrom +'] '+ sMsg);

end;

//гружу список хостов
procedure TForm1.FormActivate(Sender: TObject);
begin
ComboBox1.Items.LoadFromFile('c:\hosts.txt');
end;

//отправляю мессу
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
NMMsg1.FromName := Edit2.Text;
NMMsg1.Host := ComboBox1.Items[ComboBox1.ItemIndex];
NMMsg1.PostIt(Memo3.Text);
end;
end.


Ответить.

Ответ 1:


Вопрос 353:

От: Ер Тостик

У меня такая проблема:
Хочу написать программу для выбора Shell для Windows (стандартный -
explorer). Т.е. вместо explorer при загрузке запускается моя программа и
из нее выбирается к примеру Far, LiteStep или же обычный explorer. Но
при запуске explorer из моей программы открывается обычное окно
(проводник), а мне надо, чтобы загружался "рабочий стол". Видимо надо
писать не "start explorer.exe" или просто "explorer.exe", а что-то
другое?

Ссылки на _данную_ тему (если есть)?


Ответить.

Ответ 1:


Вопрос 354:

От: Ziv

:Такой вот вопрос, нужно из Делфака позвонить через модем, как это
можно сделать. Если можно, небольшой пример.


Ответить.

Ответ 1:


Вопрос 355:

От: MadAM


У меня к вам простой вопрос - можно ли как-нить заставить работать
программку, написанную в Делфи для работы с БД, если на компе не
установлена Делфи (BDE)?


Ответить.

Ответ 1:


Вопрос 356:

Вопрос:
От: Евгений Морозов

Как решить проблему: имеется текстовый файл, нужно его напечатать на
матричном принтере в _текстовом_ режиме, а не в графике. Метод с
использованием AssignFile...WriteLn...CloseFile не подходит, т.к.
нужно, чтобы отправляемые на печать задания ставились в очередь (т.е.
задействовать спулер Windows, как это реализовано в FAR'е (печать по
Ctrl+F5).


Ответить.

Ответ 1:


Вопрос 357:

От: vahrshev@yandex.ru

Есть Win2000Server, к нему по COM порту коннектиться другая машина.
Устанавливается соедтнение. Как из Делфей отключить этого пользователя
на сервере?


Ответить.

Ответ 1:


Вопрос 358:

От: Ольта Константин

Здравствуйте дамы и господа!

Для вывода помощи (хелпика) в программе использую RichEdit. Проблема -
вытаскиваю файл помощи в RichEdit из *.RTF, а он у меня с гиперссылками.
Гиперссылки указывают на определенные абзацы в документе (не на другие
файлы). В RichEdit гиперссылки не работают. Есть ли возможность сделать
гиперссылки рабочими в RichEdit?


Ответить.

Ответ 1:


Вопрос 359:

От: Westa

Добрый день!
Есть база Paradox, формируется SQL - запрос по таблице, если запись
содержит русские буквы Ч или Я, то эти записи не распознаются. Как
быть???


Ответить.

Ответ 1:


Вопрос 360:

От: Олег Гончаренко

Выполняю следующую процедуру : NMMsg1.PostIt(Memo1.Text),
если удаленная машина отключена получаю сообщение
'Connection Failed'.... Как блокировать это сообщение,
а показать свое? Или каким образом при запуске проги
получить список IP-адресов машин которые готовы
вступить в контакт?
Заранее благодарен! Буду рад примеру или ссылке на
литературу....


Ответить.

Ответ 1:


4. Отвеченные вопросы.
----------------------


Вопрос 176:

От: Egorov

Здравствуйте!
Если можете ответьте пожалуйста на такой вопрос: Как программно
прочитать (и изменить!) настройки Панели Управления, например, как
узнать разделитель целой и дробной части числа или даты?
Заранее благодарю,


Ответить.

Ответ 1:
В панеле управления никаких настроек не храниться! Там
только специальные DLL типа CPL храняться - т.е.
исполняемый код. Сами настройки лежат в реестре, ini
файлах и еще кой-где, в каждом конкретном случае в
своем месте, откуда и можно их вытянуть, впрочем для
наиболее общих есть специальные функции их вывода. В
данном случае ничего и не надо делать а это значение
уже храниться в системной переменной
"DecimalSeparator"
модуль - "sysutils"
Ответ 2:
Набери в Help строку ' DecimalSeparator variable ' и там ты найдешь ответ


Вопрос 177:

От: www.irop.de

Огромное спасибки за помощь всем великим программистам!
А дату отнять от даты: Edit1.Text :=
IntToStr(Round(DateTimePicker1.Date - DateTimePicker2.Date))
Так глядишь и программирование начнёшь понимать...
А теперь у меня очень серьёзный вопрос. Думаю многим может пригодиться:
У меня база данных в Excel97 и я не хочу переписывать. Мало места
занимает, наглядно
и сохранять легко на дискете. Везде открыть можно...
Но создал Форму для поиска необходимого человека, а увязать не могу.
Т.е. мне надо набрать н-р Ульяновск, а форма покажет 1-го человека из
таблицы со всеми данными, если это не он, нажму "искать следущего" и
т.д.
Хочу точно знать, что установить в свойствах для TTable, DataSource и
т.д.
И даже ссылка на таблицу должна быть на форме, вдруг место поменяет
(н-р: на дискету).


Ответить.

Ответ 1:
Во первых используй место TTable TQuery и напиши SQL
Select * From Имя Таблицы Where Поле = значение


Вопрос 178:

От: Westa

А подскажите, как записи из поля таблицы преобразовать в массив?


Ответить.

Ответ 1:
Придется руками перебрать все записи. Что-то типа:

var
Mas : array[0..СколькоНадо] of ТвойТип; (integer, string, etc...) по потребности
i : integer;

Begin
i := 0;
ТвояТаблица.Open;
while not ТвояТаблица.EOF do begin
Mas[i] := ТвояТаблица['ТвоеПоле'];
Inc(i);
ТвояТаблица.Next;
end;
ТвояТаблица.Close;
End;
Ответ 2:
Я думаю этот код вам поможет (но вобще не мешает читать книжки)

Query.Close;
Query.Sql.Clear;
S_SQL:='Select * From Таблица'; // S_SQL типа string (любой необходимый запрос)
Query.Sql.Add(S_SQL);
Query.Open;
i:=0;
while not Query.EOF do
begin
Array[i]:=Query.FieldByName('Имя поля').Value);
Query.Next;
i:=i+1;
end;


Вопрос 179:

От: Dmitry

У меня следующая проблема. Запускается DOS-задача. Из под нее запускается
Delphi-задача. Необходимо вернуть фокус ввода обратно в DOS-задачу.
API функции типа FindWindows, BringWindowToTop(HWND);
выполняются но активным остается окно из которого запускается Delphi-задача.
Для упрощения я попытался активизировать хотя бы окно WORD но и с ним у меня
ничего не получается:
my_HWND :=FindWindow(nil,'Microsoft Word - Документ1');
windows.SetFocus(my_HWND);
Под отладчиком дескриптор WORD виден но активным WORD не становиться.


Ответить.

Ответ 1:
Для того, чтобы узнать HWND окна надо использовать H:=FindWindow('Класс','Заголовок');
Для того, чтобы узнать класс окна надо использовать программу WinSight32, которая в поставке ДЕЛьФинЫ или гораздо
более удобную программу
WindInfo Даниила Карапетяна, которую можно взять здесь http://delphi4all.narod.ru/prog/windinfo.zip

З.Ы.
Все ДОС программы в Винде имеют класс "tty"
З.З.Ы.
Для твоего случая
my_HWND :=FindWindow('OpusApp','Microsoft Word - Документ1');
windows.SetFocus(my_HWND);
Ответ 2:


Вопрос 180:

От: school73


Здравствуйте!
Нужно из Delphi создать документ Word, дать ему
имя, нарисовать табличку и скачать туда, кое-какие
данные из базы. Если не сложно, пришлите команды работы
с таблицами Word.
Богданова Рита.


Ответить.

Ответ 1:
на сайте Microsoft есть полное описание структуры файла Word-6/97
файл называется gc0165.doc
если нужно могу присласть - примерно 760kb
Я в своей бухгалтерской программе генерирую файл в формате word 6.0 (для
совместимости со старыми версиями) и это оказалось много проще чем
выводить на печать через генератор отчетов.
Ответ 2:
С Word не знаю, а под Exel все хорошо прописано в 1С.
Берешь какую-нибудь конфигурацию и ищешь переслать или напечатать в
Exel и там на форме довольно неплохо написано как работать с Офисом,
но к сожалению функции на русском ( очень трудно сначала разобраться)=
Ответ 3:
см. примеры в самом Delphi там есть нечто подобное
у меня у самого есть пример как сделать тоже самое в Excel
(с Word'ом просто не разбирался) так что см. ниже если это поможет конечно
:-)))
Это полностью рабочий вариант единственно что надо подключить модуль

#include <ComObj.hpp>

и написано все это под C++ Builder (но это надеюсь не проблема)

void __fastcall TForm1::aExportExcelExecute(TObject *Sender)
{
Variant XL,v0,v1,v2,v3;
int MaxLength,CodeMaxLength;
float sum;
int TopIndent;
AnsiString s;

DateSeparator = '.';
ShortDateFormat = "dd.mm.yyyy"
TopIndent=5;


MaxLength=((AnsiString)"???????????? ??????").Length();
CodeMaxLength=((AnsiString)"??00000 ").Length();

Scroll=false;
BasketQuery->First();
sum=0;

for (int i=0;i<BasketQuery->RecordCount;i++)
{
s=String(BasketQuery->FieldValues["product_name"]);// ??????????
????????? ?????? ??? ??????????? ???????????? ?????
if (s.Length()>MaxLength)
MaxLength=s.Length();
/*
s=String(BasketQuery->FieldValues["code"]);
if (s.Length()>CodeMaxLength)
CodeMaxLength=s.Length();
*/
BasketQuery->Next();
}

MaxLength+=3;

XL=CreateOleObject("Excel.Application");
//XL.OlePropertySet("Visible",true);
v0=XL.OlePropertyGet("Workbooks");
v0.OleProcedure("Add");
v1=v0.OlePropertyGet("Item",1);
v0=v1.OlePropertyGet("Worksheets") ;
v0.OlePropertyGet("Item",1).OlePropertySet("Name","?????");
//v0.OlePropertyGet("Item",2).OlePropertySet("Name","??????????? ???????");
v1=v0.OlePropertyGet("Item",1);
v3=v1.OlePropertyGet("Columns");
v3.OlePropertyGet("Item",1).OlePropertySet("ColumnWidth",CodeMaxLength);
v3.OlePropertyGet("Item",2).OlePropertySet("ColumnWidth",MaxLength);
v3.OlePropertyGet("Item",3).OlePropertySet("ColumnWidth",((AnsiString)"?????
?????").Length());
v3.OlePropertyGet("Item",4).OlePropertySet("ColumnWidth",((AnsiString)"1 234
567,00").Length());
v3.OlePropertyGet("Item",5).OlePropertySet("ColumnWidth",((AnsiString)"1 234
567,00").Length());



//v3.OlePropertySet("Width",200);

//
v1.OlePropertyGet("Cells").OlePropertyGet("Item",1,2).OlePropertySet("Value"
,"");
s="????? : ?"+String(OrderQuery->FieldValues["order_id"])+", ??????? "

+((TDateTime)OrderQuery->FieldValues["order_date"]).FormatString("dd.mm.yyyy
")
+" ?
"+((TDateTime)OrderQuery->FieldValues["order_date"]).FormatString("hh:mm:ss"
);

v1.OlePropertyGet("Cells").OlePropertyGet("Item",1,1).OlePropertySet("Value"
,s);
v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",1,1);
v2.OlePropertyGet("Font").OlePropertySet("Color",clBlack);
v2.OlePropertyGet("Font").OlePropertySet("Bold",true);
v2.OlePropertyGet("Font").OlePropertySet("Size",12);

s="?????? : "+DealerQuery->FieldValues["clientname"];

v1.OlePropertyGet("Cells").OlePropertyGet("Item",2,1).OlePropertySet("Value"
,s);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",2,1).OlePropertyGet("Fon
t");
v2.OlePropertySet("Color",clBlack);
v2.OlePropertySet("Bold",true);
v2.OlePropertySet("Size",12);
/*
s="???? :
"+((TDateTime)String(OrderQuery->FieldValues["order_date"])).FormatString("d
d.mm.yyyy");

v1.OlePropertyGet("Cells").OlePropertyGet("Item",3,1).OlePropertySet("Value"
,s);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",3,1).OlePropertyGet("Fon
t");
v2.OlePropertySet("Color",clBlack);
v2.OlePropertySet("Bold",false);
v2.OlePropertySet("Size",12);

s="????? :
"+((TDateTime)String(OrderQuery->FieldValues["order_date"])).FormatString("h
h:mm:ss");

v1.OlePropertyGet("Cells").OlePropertyGet("Item",4,1).OlePropertySet("Value"
,s);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",4,1).OlePropertyGet("Fon
t");
v2.OlePropertySet("Color",clBlack);
v2.OlePropertySet("Bold",false);
v2.OlePropertySet("Size",12);

*/

v1.OlePropertyGet("Cells").OlePropertyGet("Item",TopIndent-1,1).OlePropertyS
et("Value","???");

v1.OlePropertyGet("Cells").OlePropertyGet("Item",TopIndent-1,2).OlePropertyS
et("Value","???????????? ??????");

v1.OlePropertyGet("Cells").OlePropertyGet("Item",TopIndent-1,3).OlePropertyS
et("Value","??????????");

v1.OlePropertyGet("Cells").OlePropertyGet("Item",TopIndent-1,4).OlePropertyS
et("Value","????");

v1.OlePropertyGet("Cells").OlePropertyGet("Item",TopIndent-1,5).OlePropertyS
et("Value","?????????");

//
v1.OlePropertyGet("Cells").OlePropertyGet("Item",4,6).OlePropertySet("Value"
,"?????? 2");

v2=v1.OlePropertyGet("Range","A"+IntToStr(TopIndent-1)+":E"+IntToStr(TopInde
nt-1));

// v2.OlePropertySet("WrapText",false);
// v2.OlePropertyGet("Font").OlePropertySet("Color",clYellow);

v2.OlePropertyGet("Font").OlePropertySet("Bold",true);
v2.OlePropertyGet("Font").OlePropertySet("Size",10);
// v2.OlePropertyGet("Font").OlePropertySet("Name","Arial");

// v2.OlePropertyGet("Interior").OlePropertySet("ColorIndex",16);

s="D1:E"+IntToStr((int)BasketQuery->RecordCount+TopIndent);
v2=v1.OlePropertyGet("Range",s);
v2.OlePropertySet("NumberFormat","# ###,00");


s="A"+IntToStr(TopIndent-1)+":E"+IntToStr((int)BasketQuery->RecordCount+TopI
ndent-1);
v2=v1.OlePropertyGet("Range",s);
v2.OlePropertyGet("Borders").OlePropertySet("Weight",xlHairline);



/* v2=v1.OlePropertyGet("Range","A7:F7");
v2.OlePropertyGet("Borders").OlePropertySet("Weight",xlThin);

v2=v1.OlePropertyGet("Range","A5:F5");

v2.OlePropertyGet("Borders",xlEdgeBottom).OlePropertySet("LineStyle",xlDash)
;
*/

BasketQuery->First();

ProgressBar1->Max=BasketQuery->RecordCount;
ProgressBar1->Position=0;

for (int i=TopIndent;i<BasketQuery->RecordCount+TopIndent;i++)
{

v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,1).OlePropertySet("Value"
,String(BasketQuery->FieldValues["code"]));

v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,2).OlePropertySet("Value"
,String(BasketQuery->FieldValues["product_name"]));

v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,3).OlePropertySet("Value"
,String(BasketQuery->FieldValues["amount"]));

//v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,4).OlePropertySet("Valu
e",String(BasketQuery->FieldValues["price"]));

v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,4).OlePropertySet("Value"
,String(BasketQuery->FieldValues["price"]));

s=FloatToStr(StrToFloat(String(BasketQuery->FieldValues["amount"]))*StrToFlo
at(String(BasketQuery->FieldValues["price"])));

v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,5).OlePropertySet("Value"
,s);

sum+=StrToFloat(String(BasketQuery->FieldValues["amount"]))*StrToFloat(Strin
g(BasketQuery->FieldValues["price"]));
v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,1);
v2.OlePropertyGet("Font").OlePropertySet("Color",clBlack);
v2.OlePropertyGet("Font").OlePropertySet("Bold",false);
v2.OlePropertyGet("Font").OlePropertySet("Size",10);
// v2.OlePropertyGet("Interior").OlePropertySet("ColorIndex",40);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,2);
v2.OlePropertyGet("Font").OlePropertySet("Color",clBlack);
v2.OlePropertyGet("Font").OlePropertySet("Bold",false);
v2.OlePropertyGet("Font").OlePropertySet("Size",10);
// v2.OlePropertyGet("Interior").OlePropertySet("ColorIndex",36);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,3);
v2.OlePropertyGet("Font").OlePropertySet("Color",clBlack);
v2.OlePropertyGet("Font").OlePropertySet("Bold",false);
v2.OlePropertyGet("Font").OlePropertySet("Size",10);
// v2.OlePropertyGet("Interior").OlePropertySet("ColorIndex",34);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,4);
v2.OlePropertyGet("Font").OlePropertySet("Color",clBlack);
v2.OlePropertyGet("Font").OlePropertySet("Bold",false);
v2.OlePropertyGet("Font").OlePropertySet("Size",10);
// v2.OlePropertyGet("Interior").OlePropertySet("ColorIndex",34);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",i,5);
v2.OlePropertyGet("Font").OlePropertySet("Color",clBlack);
v2.OlePropertyGet("Font").OlePropertySet("Bold",true);
v2.OlePropertyGet("Font").OlePropertySet("Size",10);
// v2.OlePropertyGet("Interior").OlePropertySet("ColorIndex",35);


ProgressBar1->Position++;
BasketQuery->Next();
}

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",(int)BasketQuery->Record
Count+TopIndent,5);
v2.OlePropertySet("Value",sum);

v2=v1.OlePropertyGet("Cells").OlePropertyGet("Item",(int)BasketQuery->Record
Count+TopIndent,4);
v2.OlePropertySet("Value","????? :");

s="A1:E"+IntToStr((int)BasketQuery->RecordCount+TopIndent-1);
v2=v1.OlePropertyGet("Range",s);
v2.OleFunction("BorderAround",xlDouble,xlMedium,1);

s="D"+IntToStr((int)BasketQuery->RecordCount+TopIndent)+":E"+IntToStr((int)B
asketQuery->RecordCount+TopIndent);
v2=v1.OlePropertyGet("Range",s);
v2.OleFunction("BorderAround",xlDouble,xlMedium,1);
v2.OlePropertyGet("Font").OlePropertySet("Bold",true);


XL.OlePropertySet("DisplayAlerts",false); //????????? ??????????? ???
???????? ???????
if (SaveDialog1->Execute())

XL.OlePropertyGet("Workbooks").OlePropertyGet("Item",1).OleProcedure("SaveAs
",SaveDialog1->FileName);

ProgressBar1->Position=0;

XL.OleProcedure("Quit");
}

Ответ 4:
Есть для этого случая очень хороший компонет - Ekrtf.

Вопрос 181:

От: Александр Федюнин


Вопрос: А кто-нибудь знает, можно ли в Дельфи подключить кларионовскую
базу и если можно то как?


Ответить.

Ответ 1:
Есть MapObject от фирмы ESRI (www.esri.com). Реализует отображение карт с
настройкой всех параметров. Но дорого!

Вопрос 182:

От: Миленький


Как получить исходный текст html-странички, не используя свойство
SourceText компонента THTML, а используя какие-нибудь другие компоненты,
например: TWebBrowser.
И еще. Подскажите, где взять что-нибудь (VCL, ActiveX-компоненты) для
парсинга строк, например сохранение всех ссылок из html-странички и т.п.



Ответить.

Ответ 1:
Загляните на http://delphi.mastak.com/,
там есть несколько статей по интересующим Вас темам.


Вопрос 183:

От: Popov Eugene

У меня следующий вопрос:
Строю график двух переменных (например x:=cos(t); y:=sin(t)) используя
TeeChart v4 (тип Line/FastLine), так у меня вместо окружности фигня
какая то получается - оно соединяет точки отрезками не в том порядке, в
котором я делаю Series1.AddXY, а как будто сортирует их по горизонт.
координатам (визуально выглядит как закрашенный круг). Т.е. если график
- что нибудь типа прямой или параболы, то все OK.
Можно ли это победить?
Может кто подскажет компонент для построения графиков, с возможностью
рисования на графике и простой в использовании.


Ответить.

Ответ 1:
Компонент TChart по моему не нужен для отрисовки таких
простых функций. Попробуйте какой-нибудь компонент из
стандартного набора Delphi (по моему PaintBox), позво-
ляющий рисовать на Canvas'е. Все делается просто: привязка
к координатам канваса, рисуются оси (LineTo), затем выводи-
тся функция по точкам. Единственное неудобство может быть
с перемещением начала координат (на Canvas'е оно находится
в верхнем левом углу), но для этого можно написать свою фун-
кцию, изменяющюю координаты точек.
Ответ 2:
Надо брать не Line/FastLine, из закладки Extendet -> Polar.


Вопрос 184:

От: Сергиенко Максим

Вопрос:
Здравствуйте
Как поместить на вкладку "Servers" какой нибудь СОМ-сервер, например ИЕ или
MS SQL Server
Спасибо


Ответить.

Ответ 1:
В лоб не получиться. Надо написать собственный
компонент к интерфейсу сервера, впрочем это задача не
из сложных, вопрос в том, в надо ли это? Проще просто
использовать интерфейс вместо компонента и дело с концом.


Вопрос 185:

От: SeRj


Вопрос:

Создаю *.ini файл, в нем:

[Options]
Dametr_valov_ustanovki=123, 321, 456, 654

Запятые в данном случае разделяют числа, мне нужно в ComboBox поместить
эти четыре значения, чтобы
выпадающий список показал:
123
321
456
654
Помогите советом или лучше кодом примера.


Ответить.

Ответ 1:
Считывать как строку и парсить по запятым
Ответ 2:
Обычно делают так:
1) Надо в разделе создать ключ COUNT и присвоить ему количество
значений
2) Ниже написать ключи значений + номер значения

Т.е.:
[DIAM_SECTION]
COUNT=3
DIAM_1=123
DIAM_2=456
DIAM_3=789

Читать циклом от 1 до COUNT
Ответ 3:
Sozdai na forme button s name='LoadBtn' i ComboBox1
a kod vot on.

unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, inifiles;

type
TForm1 = class(TForm)
LoadBtn: TButton;
ComboBox1: TComboBox;
procedure LoadBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

const
SECTION_NAME: string='Options';
ID_NAME: string='Diametr_valov_ustanovki';
DELIMETER: string=',';


procedure TForm1.LoadBtnClick(Sender: TObject);
var
IniFileName, bufstr: string;
MyIni: TIniFile;
i: integer;
begin

{Opredelnie imeni ini file; ParamStr(0)-eto imya exe-module application }
IniFileName:=StringReplace(ParamStr(0), '.exe', '.ini',
[rfReplaceAll, rfIgnoreCase]);

try
{Creating ini-file}
MyIni:=TIniFile.Create(IniFileName);

{reading string from ini-file}
bufstr:=MyIni.ReadString(SECTION_NAME, ID_NAME, '');

{replacing delimeter with CR and LF}
ComboBox1.Items.Text:=StringReplace(bufstr, DELIMETER, #13#10,
[rfReplaceAll, rfIgnoreCase]);

{triming leading and trailing blanks}
for i:=0 to ComboBox1.Items.Count-1 do
ComboBox1.Items[i]:=trim(ComboBox1.Items[i]);


MyIni.Free;

except
on e:Exception do ShowMessage(e.Message);
end;


end;

end.
Ответ 4:
Советую не мучится и не изобретать велосипед.
Используйте компонент FormStorage из библиотеки RX Library.
В нем можно не только сохранять свойства объектов (в т.ч. строки
ниспадающего списка), но и сохранять значения некоторых переменных.

Вопрос 186:

От: "Зюка"

Я создаю телефонный справочник (открываю БД только для чтения) используя
DBGrid, а для поиска добавляю кучу полей Edit. А можно ли было бы
вводить тлф. номер прямо в DBGrid, но она бы не редактировалась, а
осуществлялся бы поиск по данному полю?


Ответить.

Ответ 1:
Прямо в DBGrid на мой взгляд будет слишком сложно, можно обрабатывать
событие OnKeyPress компонента DBGrid:

procedure TSubscriber_frm.RxDBGrid1KeyPress(Sender: TObject;
var Key: Char);
begin
// если набор номера (численного значения)
if ((Ord(key)>=48) and (Ord(key)<=57)) or ((Ord(key)>=96) and (Ord(key)<=105)) then begin
edit1.Visible:=True;
edit1.SetFocus;
edit1.Text:=key;
edit1.SelStart:=1;
end;
// если набор текста
if (Ord(key)>=192) and (Ord(key)<=255) then begin
edit2.Visible:=True;
edit2.SetFocus;
edit2.Text:=key;
edit2.SelStart:=1;
end;
end;
'
, а в обработке события OnChange edit1 и edit2 применить
ф-цию FindNearest по нужному полю. Прятать edit-ы , после
удачного поиска, либо по нажатии пользователем стрелки, Enter-a
и т.п. (как душе угодно) можно обрабатывая OnKeyDown edit-ов.
У меня подобная штука работает без проблем. Описана в литературе
как "инкрементальный поиск".
Ответ 2:
V primere ispolzovalsya Microsoft SQL table test

CREATE TABLE [PRODDTA].[test] (
[code] [int] NOT NULL ,
[naim_clt] [varchar] (15) NOT NULL ,
[ddd] [datetime] NULL
)

Zapros byl takoi

select code, convert(varchar, code) as code_str,
naim_clt,
ddd, replace(convert(varchar, ddd, 105), '-', '/') as
ddd_str
from test

Note: code (integer) i ddd (datetime) prishlos konvertirovat v string, tak
kak
Locate delayet chastichny poisk tolko po stringam.
To est esli ty stoish na code (integer) i hochesh naiti naprimer
znacheniye 10034,
to Locate naidet ego tolko esli ty naberesh vse znacheniye,
a esli ty vstanesh na ego stringovom analoge code_str, to Locate
nachnet iskat ego uje pri nabore 100
Eto kasaetsya takje i ddd (datetime)

Brgds,
Anar Abdullayev







unit Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, ADODB, Grids, DBGrids, ExtCtrls;

type
TForm1 = class(TForm)
Grid: TDBGrid;
ADOConnection1: TADOConnection;
test: TADODataSet;
testcode: TIntegerField;
testcode_str: TStringField;
testnaim_clt: TStringField;
testddd: TDateTimeField;
testddd_str: TStringField;
DataSource1: TDataSource;
RB_Open: TRadioButton;
RB_Close: TRadioButton;
Timer: TTimer;
procedure RB_OpenClick(Sender: TObject);
procedure RB_CloseClick(Sender: TObject);
procedure GridKeyPress(Sender: TObject; var Key: Char);
procedure TimerTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}


var
SearchString: string;

const
{V techenii etogo vremeni (milliseconds) budet soxranyatsya nabor}
TIMER_INTERVAL: integer=1000;

procedure TForm1.RB_OpenClick(Sender: TObject);
begin
{otkrytie query}
try
Test.Open;
except
on e:Exception do
begin
ShowMessage(e.Message);
RB_Open.Checked:=False;
end;
end;
end;

procedure TForm1.RB_CloseClick(Sender: TObject);
begin
Test.Close;
end;

procedure TForm1.GridKeyPress(Sender: TObject; var Key: Char);
begin
{esli timer ne vklyuchen - vkluchit}
if not timer.Enabled then timer.Enabled:=True;

{dobavleniye najatoi klavishi k naboru}
SearchString:=SearchString+key;

{neposredstvenno poisk}
Test.Locate(Grid.SelectedField.FieldName, SearchString,
[loCaseInsensitive, loPartialKey])

end;

procedure TForm1.TimerTimer(Sender: TObject);
begin
{vremya isteklo - nabor ochishaetsya, timer vyklyuchaetsya}
SearchString:='';
Timer.Enabled:=False;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
timer.Interval:=TIMER_INTERVAL;
end;

end.
Ответ 3:
Можно, обрабатывая OnKeyPress свойство DBGrid и
позиционируя курсор(я имею ввиду курсор базы данных а
не экранный курсор) в ручную чем нибудь типа Locate
или FindKey на базе данных.


Вопрос 187:

От: ION


Вопрос:Как сделать полноэкранный режим програмы?
Можно ли менять разрешение в програме?


Ответить.

Ответ 1:
Полноэкранный режим работы можно сделать установив свойство
формы WindowState в wsMaximized, тогда ест-но форма будет
находится в развернутом во весь экран виде. Чтобы форма ос-
тавалась в wsNormal и занимала весь экран можно воспльзовать-
ся следующим кодом:

procedure TFMain.FormShow(Sender: TObject);
var
Rect: TRect;
begin
SystemParametersInfo(SPI_GETWORKAREA, 0, @Rect, 0);
Left := Rect.Left;
Top := Rect.Top;
Width := Rect.Right - Rect.Left;
Height := Rect.Bottom - Rect.Top;
end;

Размер панели задач также можно определить и учесть в размерах
формы:

function GetTaskBarRectangle: TRect;
begin
GetWindowRect(FindWindow('Shell_TrayWnd', Nil), Result)
end;
Ответ 2:
Лучше всего и то, и то делать через DirectDraw.


Вопрос 188:

От: Ivan Maroz

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


Ответить.

Ответ 1:
Что касается градиентной заливки:

Есть такая функция в API <RGB(Byte R, Byte G, Byte B)>
возвращает значение, которое прямым преобразованием типов переходит в
TColor.

Нужно в памяти создать Canvas, нужной высоты и шириной пикселей 10.
Закрасить его градиентом меняя один из параметров
в RGB, затем этим Canvas-ом закрасить всю область формы.
Все!
Ответ 2:
нет проблем :-)
//градиентная заливка формы
procedure TForm1.FormPaint(Sender: TObject);
var
Row, Ht: Word ;
begin
Ht := (ClientHeight + 255) div 256 ;
for Row := 0 to 255 do
with Canvas do begin
Brush.Color := RGB(0, 0, Row) ;
FillRect(Rect(0, Row * Ht, ClientWidth, (Row + 1) * Ht)) ;
end ;
Ответ 3:
Для градиентной заливки формы я использовал набор
компонент MagiKit версии 2.5. Компонент называется
TMagicPanel. Правда не знаю будет ли он работать в
Delphi 5 (я его использовал в 4 Delphi).
Ответ 4:
unit Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
procedure FormResize(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FillForm(color: integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

const
RED_FULL: integer=1;
GREEN_FULL: integer= 256;
BLUE_FULL: integer= 65536;


procedure TForm1.FillForm(color:integer);
var
y: Word;
coef: real;
begin

coef:=256/Height;

for y:=0 to Height do
begin
Canvas.MoveTo(0, y);
Canvas.Pen.Color:=round( coef*y)*color;
Canvas.LineTo(Width, Y);
end;

end;


procedure TForm1.FormResize(Sender: TObject);
begin
Fillform(BLUE_FULL);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
Fillform(BLUE_FULL);
end;

end.
Ответ 5:
Насколько я понял, тебе надо получить возможность плавного перехода от одного цвета к другому. Для того,
чтобы добиться этого эффекта, надо иметь в виду, что значением свойства Color могут быть не только
стандартные значения(clBlack,clGreen...) но и просто число от $00000000 до $00FFFFFF то есть от 0 до
16777215. Для того, чтобы сделать то что ты говоришь удобно поступить так:
1. Написать функцию, аргументами которой были бы составляющие красного, зеленого и синего цветов(то есть
RGB). Данная функция должна переводить RGB в число от 0 до 16777215 то есть в аргумент свойства Color.
2. Далее приравняв параметры R и G к нулю, меняешь B от 255 к 0, изменяя при этом координату.

Далее я привожу пример программы:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
function GLtoColor(R,G,B: real):Int64;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.GLtoColor(R,G,B: real):Int64; // R-красный G-зеленый B- синий.

begin
If (R<1) and (G<1) and (B<1) then
GLtoColor:=Round((R+G*256+B*65536)*255) // RGB можно вводить от 0 до 1.0 как в библиотеке OpenGL
else GLtoColor:=Round((R+G*256+B*65536)); // либо от 0 до 255 как вводиться в нижеописанной функции.
end;



procedure TForm1.FormPaint(Sender: TObject);
var
i: integer;
col: int64;
begin
for i:= ClientHeight downto 0 do
begin
col:=GLtoColor(0,0,Round((i/ClientHeight)*255)); // Расчитывается цвет.
canvas.Pen.Color:=col; // Полученное значение цвета присваивается свойству Color
canvas.MoveTo(0,ClientHeight+1-i); canvas.LineTo(ClientWidth,ClientHeight+1-i); // Вывод на экран
end;
end;

end.
Ответ 6:
Наиболее простой путь на мой взгляд такой. Поставте на форму компонент Image. Установите значения его
свойств.
Align - alClient
Stretch - true.
В свойство Picture загрузите картинку с нужной градиентной заливкой. Картинку можно сделать в любом
графическом редакторе.
Ответ 7:
Существует такой компонент - TGradient, из библиотеки RX (free). К
сожалению, не помню адреса.
Второй способ - написать самому (очень толково сделано в RX :-) ).
Идея в том, что цвет определяется 3-мя составляющими RGB: red, green, blue.
Допустим, надо залить красным цветом.
................................................................
var r, g, b : byte;
...
r := 255;
g := 0;
b := 0;
................................................................
Затем расчитываешь, во сколько шагов нужно залить область. Исходя из этого
меняешь переменную r. Например:
..................................................................
Сanvas.Brush.Color := RGB( r, g, b );
Сanvas.FillRect( Rect( 0, 0, Width, 1 ));
For i := 1 TO 255 DO Begin
r := r-1;
Сanvas.Brush.Color := RGB( r, g, b );
Сanvas.FillRect( Rect( 0, i, Width, i+1 ));
End;
..................................................................
Вот, собссно, и все.


Вопрос 189:

От: anton

Здраствуйте.
Скажите как написать процедуру для часов(Label)так,чтобы одни часы
показывали бы одно время,а другие,к примеру,на 2 часа меньше.
Антон.


Ответить.

Ответ 1:
Я тут очень давно делал прогу в которой требовалось сделать часики с
разными поясами времени, вот процедурка:
Val - это переменная которя может принимать значения от -12 до 12
(типа часовые пояса от текущего времени)

_Hours - текущее время (часы)
Hours - переведенное время (часы)

If Val < 0 then
If Val + _Hours < 0 then
Hours := 24 + (_Hours + Val) else
Hours := _Hours + Val
else
If abs(Val) + _Hours > 23 then
Hours := (_Hours + Val) - 24 else
Hours := _Hours + Val;
Ответ 2:
Надо переводить в String-овский формат, потом переводить в integer, а потом выводить на экран.
Если надо то давно писал такую программу, там была целая куча времен.
Ответ 3:
У переменной типа TDateTime время записывается в дробной части.
Причем 1/24 - это один час, 1/24/60 - одна минута, 1/24/60/60 - одна секунда.

Например, в процедуре по таймеру для разницы в два часа это будет выглядеть так:

procedure TForm1.Timer1Timer(Sender: TObject);
var T : TDateTime;
begin
T:=Now;
Label1.Caption:=TimeToStr(T); // Текущее время
Label2.Caption:=TimeToStr(T-2/24); // На два часа меньше.
end;
Ответ 4:
Вот пример кода
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label1.Caption:=TimeToStr(Now);
Label2.Caption:=TimeToStr(Now-2/24);
end;

Вопрос 190:

От: Hecht Andreas


Как написать программу для составления списка заданий для
паралельных процессоров. Каждое задание может быть выполнено на любом
процессоре. Любое задание из списка выполняется на первом освободившемся
процессоре.


Ответить.

Ответ 1:
Советую зайти в какую-нибудь техническую библиотеку
(не электронную, в них нет) и найти книжку
этот раздел математики называется теория
массового обслуживания


Вопрос 191:

От: Alex Bull

:Добрый день,Дмитрий.
У меня достаточно специфический вопрос.
Как работать с MIDI портом в Delphi. Т.е. как отсылать и принимать
сообщения (имеются в виду просто посыл и прием одиночных байтов) через
MIDI порт аудио карты.
Буду благодарен за ответ.
С уважением,Александр


Ответить.

Ответ 1:


Вопрос 192:

От: Алексей Малиновский

Здраствуйте господа пограммисты!

У возникла необходимость имитацию движения жидкости по каким-нибудь
трубам.
Вот не знаю как лучше сделать :-(
- Можно через TShape, но не знаю как изобразить жидкость...
- Можно через TPaintBox, но это очень муторно...
Может есть какой-нить компонентик нормальный?
Господа подскажите какие-нить идейки по этому поводу?

Заранее благодарен за советы...

С уважением, Алексей.


Ответить.

Ответ 1:

A est takoi component TGauge na zakladke Samples (unit name gauges.pas)


Вопрос 193:

От: Алексей Малиновский

Здраствуйте господа пограммисты!

Господа подскажите, как сделать висячую форму, типа как в Delphi -
Object Inspector (только чтобы при активизации основной формы эта форма
не пропадала (не пряталась за неё))?

Заранее спасибо...


Ответить.

Ответ 1:
Смотри FormStyle, OnTop
Ответ 2:
Чтобы форма находилась постоянно поверх всех окон
установите ее свойство FormStyle в fsStayOnTop.


Вопрос 194:

От: Astanin Dmitry

Здравствуйте!
Пожалуйста, подскажите наилучший способ очистить TImage после рисования
на нем.


Ответить.

Ответ 1:
image:TImage;
Color:TColor;

...

Image.Canvas.Brush.Color:=Color;
Image.Canvas.FillRect(Image.ClientRect);

Заливает Image цветом Color
Ответ 2:
Image1.Picture := NIL;

Вопрос 195:

От: Dyadin Yurij

Здравствуйте.
Где можно взять компонент для Делфи4.0 подобный StringGrid, который бы
позволял выделять множество ячеек, сбрасывать информацию в буфер обмена
и обратно.


Ответить.

Ответ 1:
Попробуйте компонент F1Book (Formula One).
Она находится на странице ActiveX.
Можно выделить множество ячеек подряд или выборочно,
потом скопировать/вставить буфер обмена. Работа очень похожа на
MS Excel.


Вопрос 196:

От: Igor Mahnach

Здравствуйте!
Может кто-нибудь знает, где взять компонент, при помощи которого можно
организовать карту мира. Естественно, с возможностью чего-либо на этой
карте дорисовывать.
Спасибо!
Игорь


Ответить.

Ответ 1:


Вопрос 197:

От: Юрий Безсонов

Приветствую Вас.
Есть вопрос: Как можно из Делфи 5 вызвать окошко управления доступом
к файлу в NT или w2k на системе NTFS и выбранные пользователем
разрешения применить к каталогу или файлу. Это должно решаться
средствами WinAPI, но документации по нему маловато :(
Заранее благодарен.


Ответить.

Ответ 1:


Вопрос 198:

От: Загорский Антон

Здравствуйте.
У меня вот какая проблема:
Я пишу своеобразный почтовик, и там есть функция "Просмотреть полученное
письмо через ИЕ".
Стоит задача: переслать всё это в ИЕ из Lines объекта Memo1.
Создавать временный файл и потом через WinExec и через Clipboard+SendMessage
мне не хочется.
Я узнал что существует так называемые pipe-каналы или просто pipe.
Скажите, как с ним (pipe) работать. (В хелпе есть описание но там нет
примеров, да тем более он на английском. если у Вас есть толковый хелп по
win32 developer's references (вроде так, у меня это файл win32sdk.hlp) на
Русском языке то пожалуйста вышлите мне его.


Ответить.

Ответ 1:


Вопрос 199:

От: VVM

Здраствуйте.
Как обнулить .swp-файл?
Задали мне такое домашнее задание.



Ответить.

Ответ 1:
Если в системе, то просто запретить его использование.
А если из Дельфи - то надо поставить его размер в
system.ini и перезагрузить комп (сам не пробовал,
совет чисто теоретический)


Вопрос 200:

От: Марк Берсон

Hello Дмитрий,

Хочу спросить Вас.
Где то читал, что существуют уникальные заводские номера процессора и
винчестера.
Как до них добраться из Делфи. Хочу привязать программу к железу а не к
среде.
Заранее благодарю.


Ответить.

Ответ 1:
К процессору не знаю, а для винта могу подсказать - на
каждом винте есть дополнительная дорожка с этой
информацией. Если на винте указано что у него 200
дорожек, обращайтесь к 201 и читайте нужную
информацию, естественно не на логическом уровне. Но
это только чтение, писать туда не советую! Я в свое
время использовал другую привязку - MBR находится на
1-2 секторе, а BOOT сектор первого диска на 13м,
пишите что-нибудь между ними, эта метка переживает и
переформатирование разделов и переразбивку диска
FDisk'ом. Не переносит только физическое
форматирование, некоторые бутовые вирусы и некоторые
мененджеры загрузки - перед записью проверить - сектор
должен быть пустой.






Если Вы хотите как можно скорее получить ответ на свой вопрос, то
укажите в теме письма - delphiV,иначе письмо будет прочитано значительно
позже, если же у вас есть предложения то в теме письма укажите delphiP.

Для интересующихся - немного о себе. Работаю на
железнодорожном транспорте ведущим программистом.
Основные мои разработки это сбор и доставка клиентам
информации о вагонах и поездах: где находится(по России),
куда едет. В связи с этим программировал для e-mail,Socket,БД,ISAPI.

За сим прощаюсь - скорых Вам и качественных программ.

Автор рассылки - Дмитрий.
ICQ - 89533941.

ВСЕ ВОПРОСЫ СПРОСИТЬ ПРЕДЛОЖИТЬ АРХИВЫ СКОЛЬКО НАС



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться Рейтингуется SpyLog

В избранное