Masters of Delphi
 Сайт клуба любителей Delphi 
· FAQ · Статьи · Конференции · Ссылки · Новости мира компонент ·

Часто задаваемые Вопросы.. F.A.Q.

Дайджест от 25.11.2000

    Если Вы не нашли ответ на свой вопрос в этом дайджесте, то попробуйте найти его в основной базе.
    Поиск ведется так же и в "Круглом столе" славного "Королевства дельфи".
    И в разделе "Взаимопощь" на www.infoart.ru
Ключевые слова
Напоминаем, Вы можете получать лучшие вопросы на свой email !!! Достаточно подписаться на нашу почтовую конференцию.
 
Прочее


Помогите с серийным номером Delphi 5.0
»»» Юрий (08.06.00 09:50)
Купил диск "Программисту 2000". Хотел поставить с него
Borland Delphi 5.0, но нигде на диске нет серийного номера. Если кто встречался с этой проблемой, помогите.

»»» Mike Goblin - mgoblin@mail.ru (08.06.00 10:26)
Номер 111111111(ну все единицы)
Ключ fex1-91x0
Если че есть генератор ключей

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Создание отчета в MS Word


(Пример для Delphi 1.0 поскольку в Delphi 2-3 лучше
использовать:
var MsWord : variant;
MsWord := CreateOleObject('Word.Basic'); Для Delphi 3, пример ниже)

Создавать отчет в программе Word удобно если отчет имеет сложную структуру (тогда его быстрее создать в Word, чем в Qreport от Delphi, кроме того, этот QReport имеет "глюки"), либо, если после создания отчета его нужно будет изменять. Итак, первым делом в Word создается шаблон будущего отчета, это самый обыкновенный не заполненный отчет. А в места куда будет записываться информация нужно поставить метки. Например (для наглядности метки показаны зеленым цветом, реально они конечно не видны):

Накладная ? Num
























?

Поставщик

Наименование
товара

Код товара

Кол-во

Цена

Сумма

Table            




Сдал_______________________ Принял________________________
М.П. М.П.





Далее в форму, откуда будут выводиться данные, вставляете компоненту DdeClientConv из палитры System. Назовем ее DDE1. Эта компонента позволяет передавать информацию между программами методом DDE. Свойства:
ConnectMode : ddeManual - связь устанавливаем вручную
DdeService : (winword) - с кем устанавливается связь
ServiceApplication : C:\MSOffice\Winword\WINWORD.EXE - полный путь доступа к программе. (Вот здесь можно наступить на грабли. Ведь Word может лежать в любой папке! Поэтому путь доступа к нему лучше взять из реестра, а еще лучше использовать OLE см.начало раздела)

Теперь пишем процедуру передачи данных:





{ Печать накладной }
procedure Form1.PrintN;
Var
S : string;
i : integer;
Sum : double; {итоговая сумма, кстати,совет: не пользуйтесь типом real!}
Tv, Ss : PChar;
begin
S:=GetCurrentDir+'\Накладная.doc'; { имя открываемого документа }
DDE1.OpenLink; { устанавливаем связь }
Tv:=StrAlloc(20000); Ss:=StrAlloc(300); { выделяем память }
{ даем команду открыть документ и установить курсор в начало документа }
StrPCopy(Tv, '[FileOpen "'+S+'"][StartOfDocument]');
S:=NNakl.Text; { номер накладной }
{ записываем в позицию Num номер накладной }
StrCat(Tv, StrPCopy(SS, '[EditBookmark .Name = "Num", .Goto][Insert "'+S+'"]'+
'[EditBookmark .Name = "Table", .Goto]'); { и переходим к заполнению таблицы }
{ передаем данные в Word }
if not DDE1.ExecuteMacro(Tv, false) then
begin { сообщаем об ошибке и выход }
MessageDlg('Ошибка связи с Microsoft Word.', mtError, [mbOk], 0);
StrDispose(Tv); StrDispose(Ss);
exit;
end;

{ Заполняем таблицу }
Sum:=0; Nn:=0;
for i:=0 to TCount do
begin
inc(Nn);
{ предполагаем, что данные находятся в массиве T }
StrPCopy(Tv, '[Insert "'+IntToStr(Nn)+'"][NextCell][Insert "'+T[i].Company+'"]'+
'[NextCell][Insert "'+T.TName+'"][NextCell][Insert "'+T.Cod+'"][NextCell]'+
'[Insert "'+IntToStr(T.Count)+'"][NextCell]'+
'[Insert "'+FloatToStr(T.Cena)+'"][NextCell]'+
'[Insert "'+FloatToStr(T.Count*T.Cena)*+'"][NextCell]'));
inc(Nn);
Sum:=Sum+(T.Count*T.Cena); { итоговая сумма }
if not DDE1.ExecuteMacro(Tv, false)
then begin
MessageDlg('Ошибка связи с Microsoft Word.', mtError, [mbOk], 0);
exit;
end;
end;

{ Записываем итоговую сумму }
StrPCopy(Tv,
'[NextCell][Insert "Итого"][NextCell][NextCell][NextCell]'+
'[Insert "'+FloatToStr(Sum)+'"]'));
if not DDE1.ExecuteMacro(Tv, false)
then MessageDlg('Ошибка связи с Microsoft Word.', mtError, [mbOk], 0)
else MessageDlg('Акт удачно создан. Перейдите в Microsoft Word.',
mtInformation, [mbOk], 0);

StrDispose(Tv); StrDispose(Ss);
end;





Для Delphi 2 и выше
=== Cut Пример by Sergey Arkhipov 2:5054/88.10 ===

Пример проверен только на русском Word 7.0! Может, поможет...

unit InWord;
interface
uses
... ComCtrls; // Delphi3
... OLEAuto; // Delphi2
[skip]
procedure TPrintForm.MPrintClick(Sender: TObject);
var W: Variant;
S: String;
begin
S:=IntToStr(Num);
try // А вдруг где ошибка :)
W:=CreateOleObject('Word.Basic');
// Создаем документ по шаблону MyWordDot
// с указанием пути если он не в папке шаблонов Word
W.FileNew(Template:='C:\MyPath\DB\MyWordDot',NewTemplate:=0);
// Отключение фоновой печати (на LJ5L без этого был пустой лист)
W.ToolsOptionsPrint(Background:=0);

// Переходим к закладке Word'a 'Num'
W.EditGoto('Num'); W.Insert(S);
//Сохранение
W.FileSaveAs('C:\MayPath\Reports\MyReport')
W.FilePrint(NumCopies:='2'); // Печать 2-х копий
finally
W.ToolsOptionsPrint(Background:=1);
W:=UnAssigned;
end;
end;
{.....}

=== Cut Конец примера ===



Спасибо Сергею :) И еще, как определить установлен ли на компьютере Word, запустить его и загрузить в него текст из программы?



Пример:




var
MsWord: Variant;
...
try
// Если Word уже запущен
MsWord := GetActiveOleObject('Word.Application');
// Взять ссылку на запущенный OLE объект
except
try
// Word не запущен, запустить
MsWord := CreateOleObject('Word.Application');
// Создать ссылку на зарегистрированный OLE объект
MsWord.Visible := True;
except
ShowMessage('Не могу запустить Microsoft Word');
Exit;
end;
end;
end;
...
MSWord.Documents.Add; // Создать новый документ
MsWord.Selection.Font.Bold := True; // Установить жирный шрифт
MsWord.Selection.Font.Size := 12; // установить 12 кегль
MsWord.Selection.TypeText('Текст');



По командам OLE Automation сервера см. help по
Microsoft Word Visual Basic.

Ну вот и все.


НаверхПрислать свои комментарии

Можно ли из программы Delphi создавать, открывать(читать) и редактировать вордовские документы не имея установленного MS Word


Нужно знать внутренний формат файлов :((, а он от версии к версии меняется, компоненты предназначены для работы через OLE. Без установки Word-а работать не будут
-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Создание компонентов


»»» Nuke Dukem (02.08.00 14:09)
Вопросик совсем простой наверное. Как свойство родительского класса (например)
published OnChange: TNotifyEvent;
сделать в своей компоненте недоступной в Object Inspector??
И вопрос посложнее. Есть TTreeView как родительский класс для компонента. В конструкторе создаю pmenu типа TPopupMenu, owner у меню - мой TreeView. Хочу добавить в Object Inspector что-то типа PopupMenuItems от этого попапа. Простое
property PopupMenuItems : TMenuItem read GetItem;
и
function TMyTreeView.GetItem() : TMenuItem;
begin
Result:=pmenu.Items;
end;
НЕ ПОМОГЛО.
Как быть, уважаемые ???

»»» Alexander - avolkov@infostroy.ru (02.08.00 15:16)
1) На мой взгляд нужно следующее. Объявить в наследнике public свойство OnChange с соответствующими методами доступа, в которых брать или устанавливать свойство родителя:

function TMyCtrl.GetOnChange: Classes.TNotifyEvent;
begin
Result := inherited OnChange
end;

procedure TMyCtrl.SetOnChange(Value: Classes.TNotifyEvent);
begin
inherited OnChange := Value
end;

Public- свойство инспектор показывать не будет.

2) По моим наблюдениям, инспектор показывает свойство, если для него определен и read и write доступ. Как Вы будете реализовывать доступ к элементам меню - Ваш выбор. Я бы попробовал просто давать доступ к указателю на свойство pmenu.Items. Это коллекция, а с ними инспектор проблем не имеет.

»»» Alexander - avolkov@infostroy.ru (02.08.00 15:43)
Корректировка к предыдущему моему сообщение. Извините, коллекции навязли в зубах. Конечно TMenuItem это не коллекция, но инспектор с ней знаком. Поэтому проблема только в том, чтобы определить метод на запись требуемого Вам свойства.

»»» Nuke Dukem - nukedukem@iname.ru (02.08.00 15:50)
По поводу TMenuItem. Я сглупил. Если у меня создается это самое меню в конструкторе, то оно так и будет там создаваться. Даже если в IDE что-то там насоздают типа подменюшек.
В общем хотелось создать попап меню с бызовым набором строк. А в IDE можно было бы добавить/удалить/изменить. Как бы это сделать?

»»» Mike Goblin - mgoblin@mail.ru (02.08.00 16:39)
В Object Pascal уменьшить видимость метода/св-ва низя, но как правило у каждого визуального ком-та есть родитель TCustom...., где св-ва/события описаны как protected. Наследуйте от него и делайте Published нужные.
Про PopupMenu не очень понял, а чем Вас не устраивает его св-во PopupMenu для задания внешнего TPopupMenu

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Как записать сумму прописью? 123 -> сто двадцать три рубля


Не самый лучший вариант, но работает :)


{ Преобразует трехзначное число в строку }
function ConvertToWord(N : word) : string;
Const
Sot : array[1..9] of string[13] =
('сто','двести','триста','четыреста','пятьсот',
'шестьсот','семьсот','восемьсот','девятьсот');
Des : array[2..9] of string[13] =
('двадцать','тридцать','сорок','пятьдесят',
'шестьдесят','семьдесят','восемьдесят','девяносто');
Edin : array[0..19] of string[13] =
('','один','два','три','четыре','пять','шесть','семь',
'восемь','девять','десять','одиннадцать','двенадцать',
'тринадцать','четырнадцать','пятнадцать',
'шестнадцать','семнадцать','восемнадцать','девятнадцать');
Var S : string;
begin
S:=''; N:=N mod 1000;
if N>99 then begin
S:=Sot[N div 100]+' '; N:=N mod 100;
end;
if N>19 then begin
S:=S+Des[N div 10]+' '; N:=N mod 10;
end;
Result:=S+Edin[N];
end;

{ Возвращает сумму прописью }
function CenaToStr(r : Currency) : string;
Var
N,k : longint;
S : string;
begin
N:=trunc(R); S:='';
if N<>0 then begin
if N>999999 then begin
k:=N div 1000000;
S:=ConvertToWord(k);
if ((k-(k div 100)*100)>10) and ((k-(k div 100)*100)<20) then S:=S+' миллионов' else
if (k mod 10)=1 then S:=S+' миллион' else
if ((k mod 10)>=2)and((k mod 10)<=4) then S:=S+' миллиона' else
S:=S+' миллионов';
N:=N mod 1000000;
end;
if N>999 then begin
k:=N div 1000;
S:=S+' '+ConvertToWord(k);
if ((k-(k div 100)*100)>10)and((k-(k div 100)*100)<20) then S:=S+' тысяч' else
if (k mod 10)=1 then begin SetLength(S, Length(S)-2); S:=S+'на тысяча'; end else
if (k mod 10)=2 then begin SetLength(S, length(S)-1); S:=S+'е тысячи'; end else
if ((k mod 10)>=3)and((k mod 10)<=4) then S:=S+' тысячи' else
S:=S+' тысяч';
N:=N mod 1000;
end; k:=N;
S:=S+' '+ConvertToWord(k);
if ((k-(k div 100)*100)>10)and((k-(k div 100)*100)<20) then S:=S+' рублей' else
if (k mod 10)=1 then S:=S+' рубль' else
if (k mod 10)=2 then S:=S+' рубля' else
if ((k mod 10)>=3)and((k mod 10)<=4) then S:=S+' рубля' else
S:=S+' рублей';
end;
if trunc(R)<>R then begin
k:=round(frac(R)*100);
S:=S+' '+IntToStr(K);
if ((k-(k div 100)*100)>10)and((k-(k div 100)*100)<20) then S:=S+' копеек' else
if (k mod 10)=1 then begin S:=S+' копейка'; end else
if (k mod 10)=2 then begin S:=S+' копейки'; end else
if ((k mod 10)>=3)and((k mod 10)<=4) then S:=S+' копейки' else
S:=S+' копеек';
end else S:=S+' 00 копеек';
S:=Trim(S);
if S<>'' then S[1]:=AnsiUpperCase(S[1])[1];
result:=S;
end;


Еще вариант от Дмитрия (дан в конференции)

unit sumstr;

interface
uses
SysUtils, StrUtils;

function SumToString(Value : String) : string;

implementation
const a:array[0..8,0..9] of string=(
('','один ','два ','три ','четыре ','пять ','шесть ','семь ','восемь ','девять '),
('','','двадцать ','тридцать ','сорок ','пятьдесят ','шестьдесят ','семьдесят ','восемьдесят ','девяносто '),
('','сто ','двести ','триста ','четыреста ','пятьсот ','шестьсот ','семьсот ','восемьсот ','девятьсот '),
('тысяч ','тысяча ','две тысячи ','три тысячи ','четыре тысячи ','пять тысячь ','шесть тысячь ','семь тысячь ',
'восемь тысячь ','девять тысячь '),
('','','двадцать ','тридцать ','сорок ','пятьдесят ','шестьдесят ','семьдесят ','восемьдесят ','девяносто '),
('','сто ','двести ','триста ','четыреста ','пятьсот ','шестьсот ','семьсот ','восемьсот ','девятьсот '),
('миллионов ','один миллион ','два миллиона ','три миллиона ','четыре миллиона ','пять миллионов ',
'шесть миллионов ','семь миллионов ','восемь миллионов ','девять миллионов '),
('','','двадцать ','тридцать ','сорок ','пятьдесят ','шестьдесят ','семьдесят ','восемьдесят ','девяносто '),
('','сто ','двести ','триста ','четыреста ','пятьсот ','шестьсот ','семьсот ','восемьсот ','девятьсот '));
b:array[0..9] of string=
('десять ','одинадцать ','двенадцать ','тринадцать ','четырнадцать ','пятьнадцать ','шестьнадцать ',
'семьнадцать ','восемьнадцать ','девятьнадцать ');
function SumToStrin(Value : String) : string;
var s,t:string;
p,pp,i,k:integer;
begin
s:=value;
if s='0' then t:='Ноль ' else begin
p:=length(s);
pp:=p;
if p>1 then
if (s[p-1]='1') and (s[p]>'0') then begin
t:=b[strtoint(s[p])];pp:=pp-2;end;
i:=pp;
while i>0 do begin
if (i=p-3) and (p>4) then
if s[p-4]='1' then begin
t:=b[strtoint(s[p-3])]+'тысяч '+t;i:=i-2;end;
if (i=p-6) and (p>7) then
if s[p-7]='1' then begin
t:=b[strtoint(s[p-6])]+'миллионов '+t;
i:=i-2;end;
if i>0 then begin k:=strtoint(s[i]);
t:=a[p-i,k]+t;
i:=i-1;end;
end;end;
result:=t;
end;
procedure get2str(value:string;var hi,lo:string);
var p:integer;
begin
p:=pos(',',value);
lo:='';hi:='';
if p=0 then p:=pos('.',value);
if p<>0 then delete(value,p,1);
if p=0 then begin hi:=value;lo:='00';end;
if p>length(value) then begin hi:=value;lo:='00';end;
if p=1 then begin hi:='0';lo:=value;end;
if (p>1) and (pthen
begin
hi:=copy(value,1,p-1);
lo:=copy(value,p,length(value));
end;
end;

function sumtostring(value:string):string;
var hi,lo:string;
pr,er:integer;
begin
get2str(value,hi,lo);
if (hi='') or (lo='') then begin result:='';exit;end;
val(hi,pr,er);if er<>0 then begin result:='';exit;end;
hi:=sumtostrin(inttostr(pr))+'руб. ';
if lo<>'00' then begin
val(lo,pr,er);if er<>0 then begin result:='';exit;end;
lo:=inttostr(pr);
end;
lo:=lo+' коп. ';
hi[1]:=AnsiUpperCase(hi[1])[1];
result:=hi+lo;
end;
end.

НаверхПрислать свои комментарии

Перевод RTF в HTML (+)


»»» Kuzmich (24.07.00 13:33)
Может кто поможет исходниками. Нужно написать программу перевода RTF в HTML Или может кто даст дельный совет...

»»» maestro - maestro@bashneft.ru (24.07.00 14:36)
Если быть не очень разборчивым в средствах, то первое, что приходит в голову, это использовать Word как OLE-сервер. "Открыть", "Сохранить как..."

»»» Kuzmich - boriskuzma@mail.ru (24.07.00 14:43)
Согласен можно, но он (Word) сует в столько билеберды в HTML, что повесится можно...

»»» Wonder (24.07.00 16:23)
Странно, но первое что пришло мне в голову, так это использовать TRichEdit. Загружать туда, потом, если надо, править, и, далее, по-выбору: либо сохранять просто текстом, а потом ручками в HTML, либо, если текст простой, т.е. текст безо всяких там таблиц и прочего форматирования, можно и автоматизировать слегка(теги там всякие простенькие вставлять автоматически, типа

, etc.). У меня то же самое работает через TMemo, но не с RTF, а с изначально текстовыми файлами. А при наличии форматирования устанешь эту автоматизацию писать.

»»» Kuzmich - boriskuzma@mail.ru (24.07.00 16:29)
Целью этой программы должен быть перевод огромных текстов, в которых присутствуют большие таблицы, так что "ручками" не подойдет

»»» Wonder (24.07.00 16:43)
Тогда учи Rich Text Format. Как там в нем таблицы и прочая ерунда определяется. И работать придется с самим форматом. Но, честно говоря, самому это делать - беда. Наверняка уже есть готовые погаммы на эту тему.
Правда, навряд ли на DELPHI.

»»» maestro - maestro@bashneft.ru (27.07.00 13:30)
Зайди сюда:
http://people.amursu.ru/klaus/delphi_pro2.htm#1

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Как создать файл с расширением "hlp"


»»» Роман (13.07.00 00:19)
Подскажите, какой софт нужно исползовать, чтобы написать полноценный и разветвленный Help.

»»» Merlin (13.07.00 00:42)
Это на любителя, наверняка тебе тут подскажут кучу всего (таких программ не мало), но мне больше нравится "ручками" :) Как это делается подробно написано в статье Олега Зайцева, найти ее можно на www.chat.ru/~z_ol


»»» Romych (13.07.00 14:23)
Привет тезка. Могу посоветовать мастдайный продукт HTML Help Workshop, эта штука позволяет создавать не просто нелпы, а новые гипертекстовые/хтмл-ные как в самих виндах.

»»» Merlin - delphi@mastak.com (17.07.00 17:29)
Еще ссылки:

ProHelp http://www.igweb.pair.com/
IG`s Software выпустила версию 2.0 и 3.0-бета своего популярного редактора создания контекстного хелпа для проектов на Delphi 3,4,5 и C++Builder 3,4,5

HelpScribble 5.4.0 http://www.jgsoft.com/
редактор для создания Windows Help и HTML Help файлов.


-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Подскажите какие ХОРОШИЕ программы есть для создания ИНТАЛЯШЕК


»»» kingdom (26.07.00 21:19)
День добрый !

1) Поделитесь опытом, расскажите как лучше писать ИНСТАЛЯШКУ, чтобы и в реестр лазела и комп перегружала и все остальное... Есть InstallSheild Express, но это слабовато.

2)Если не сложно расскажите немного об InstallSheild (обычном), что это такое, насколько сложное и гобкое средство.

Спасибо !

»»» balda - stub@inbox.ru (27.07.00 06:50)
есть крутая прога как Wise Install Master у меня на компашке 60 метров. ну очень кульная. скрипт свой мона писать...и в реестр. я ей пользуюсь.

»»» DarkTram (30.07.00 20:17)
Vise Installer 3.0 (MindVision) - рулезная штука (~3Mb)
Нужно крякнуть.
Я использую:
Name: Kooky [HERiTAGE]
Pass: IVR400W7921285

»»» Mark - mark@kangaroonet.com (02.08.00 18:37)
Setup Factory !!!

Очень мощный и компактный инсталлятор.


»»» Vlad - v987@mail.ru (03.08.00 12:24)
По работе использую InstallSheild Prof.6.02 штука конечно мощная, но для решения общих/типовых задач... А вот как только надо сделать инсталятор разбитый на 2-е фазы (2-ая фаза после перезагрузки).. то тут начинаются приключения.. К тому же версия 6.02 удобнее чем 5.X, но и баг в ней прилично :) "немного об InstallSheild" я вроде рассказал. Подробнее могу ответить только на конкретные вопросы


»»» O$AE - osae@newmail.ru (15.08.00 13:39)
Рекомендую Wise Install Master 7.0 и выше. Интерфейс понятен, есть возможность писать на script.
Если негде взять пиши.

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Как сделать сохранение в тхт формате..


»»» Стас (15.06.00 03:30)
Я совсем юнный пользователь дельфи и пробую переделывать примеры программ,может научусь так чему нибудь..Вообщем есть в приложении подобие текстового редактора, но он сохраняет в rtf, как переделать в тхт?

»»» Mike Goblin - mgoblin@mail.ru (16.06.00 15:05)
Наверное вы используете пример редактора из дельфи.
В форме окна редактирования у компонента RichEdit установите св-во PlainText = true

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-

НаверхПрислать свои комментарии

Как работать с плагинами ?


Я сделал так - выбираю все DLL из каталога с программой, загружаю каждую и пытаюсь найти в ней функцию (через API GetProcAddress) с заранее определенным жестко именем (например что нибудь типа IsPluginForMyStuff). Если нашлась - DLL считается моим плагином, если нет - выгрузить и забыть.

А набор вызываемых функций по идее одинаков у всех плагинов, и программа (основная) в курсе какие именно функции она ищет в DLL. Если даже и не так, то ничего не мешает тебе определить в плагине функцию наподобие GetFeatures, возвращающую список строк-названий поддержанных плагином процедур.

Вот часть моего кода по работе с плагинами...

...
type
// Процедурные типы для хранения ссылок на функции плагинов
TGetNProc=function:shortstring;
TGetSProc=function:integer;
TProcessProc=procedure(config:pointer; request:PRequest; var reply:PReply);
TConfigProc=procedure(defcfg:PSysConfig; var config:pointer);
TSaveLoadProc=procedure(inifile:pointer; var config:pointer);

// Информация об отдельном плагине
TPlugin=record
Name:shortstring; // Полное название
Filename:shortstring; // Имя файла
Handle:integer; // Хэндл загруженной DLL
CFGSize:integer; // Размер конфигурации в RAM
ProcessProc: TProcessProc; // Адрес процедуры обработки
ConfigProc: TConfigProc; // Адрес процедуры настройки
LoadCFG,SaveCFG:TSaveLoadProc; // Адреса процедур чтения/записи cfg
end;
PPlugin=^TPlugin;

// Список загруженных плагинов
TPlugins=class(TList);

...

var
Plugins:TPlugins; sr:TSearchRec; lib:integer;
pgetn:TGetNProc; pgets: TGetSProc; plugin:PPlugin;

...

// Читаем плагины и создаем их список.
Plugins:=TPlugins.Create;
if FindFirst('*.dll',faAnyFile,sr)<>0 then begin
ShowMessage('Hе найдено подключаемых модулей.');
Close;
end;
repeat
lib:=LoadLibrary(PChar(sr.Name));
if lib<>0 then begin
@pgetn:=GetProcAddress(lib, 'GetPluginName');
if @pgetn=nil then FreeLibrary(lib) // Hе плагин
else begin
New(plugin);
@pgets:=GetProcAddress(lib, 'GetCFGSize');
plugin.Name:=pgetn;
plugin.Filename:=sr.Name;
plugin.CFGSize:=pgets;
plugin.Handle:=lib;
plugin.ConfigProc:=GetProcAddress(lib, 'Configure');
plugin.ProcessProc:=GetProcAddress(lib, 'Process');
plugin.SaveCFG:=GetProcAddress(lib, 'SaveCFG');
plugin.LoadCFG:=GetProcAddress(lib, 'LoadCFG');
Plugins.Add(plugin);
end;
end;
until FindNext(sr)<>0;
FindClose(sr);
...

НаверхПрислать свои комментарии

Чем принципиально отличаются классы от объектов?


»»» Palladin (28.07.00 12:39)
Чем принципиально отличаются классы от объектов?

»»» Диман - makaev@pisem.net (28.07.00 13:05)
Объект - это экземпляр класса.

»»» ASCRUS - ascrus@aport.ru (28.07.00 13:47)
если ты имеешь ввиду под понятием обьекты: обьектыне типы, которые описывались ранее в Object Pascal (ключевое слово object), то в Delphi class - это то же самое плюс свойства, события и RTTI (то есть возможность делать публицируемые свойства).

»»» Alexander - avolkov@infostroy.ru (28.07.00 13:48)
Согласен с предыдущим с точки зрения анализа. Еще - объект отличается наличием данных (атрибутов или в терминологии Delphi полей, свойств, указателей на обработчиков событий). Класс данных не имеет, кроме реализованных в виде функций класса и предопределенных в TClass атрибутов, например ClassName.

»»» SergSuper - sergsuper@mail.ru (28.07.00 14:24)
Не совсем так. Класс тоже ведь имеет данные.
t=class X:char end - X это что, не данные?
Дело в следующем. Первоначально появился object - что-то вроде record-а, но с процедурами, наследованием и т.д. Использовались обычно объекты динамически, т.е. приходилось описывать тип данных объект и тип ссылку на него. Чтобы создать нечто динамическое надо было использовать функцию New. В итоге всё получалось несколько громоздко.
В Delphi решили работать с объектами по-другому, т.е. объект(который class) это уже сразу ссылка, еще один тип объявлять не надо, New тоже не надо вызывать. Все новые возможности реализовали только в классах, а object оставили для совместимости.

Ну а принципиальные различия между class и object, как видно из вышеописаного:
1. Класс это ссылка
2. В классы реализованы новые возможности.
Если не имеются в виду паскалевские термины, то объект и класс это обычно одно и тоже, ну может быть "объект - это экземпляр класса".

»»» Alexander - avolkov@infostroy.ru (28.07.00 15:13)
Да, тут нечего сказать. Super поставил жирную точку в дискусси, не удосужившись понять о чем я писал.
Написав "t=class X: char; end;" Вы не сможете обратиться к данным "t.X := #13;", поскольку память под эти "данные" не выделена. Понятно? Не верите, можете попробовать. И вообще, прежде чем писать пример кода, неплохо было бы его хотя-бы откомпилировать без ошибок.

»»» Диман - makaev@pisem.net (28.07.00 15:38)
Вот я и говорю: Объект - это экземпляр класса.
т.е. объект, это тотже класс, под который выделена
память и с которым уже можно работать.

»»» SergSuper - sergsuper@mail.ru (28.07.00 16:02)
Ну зачем же так. Очень я даже удосужился.
А Ваш последний мессаждь действительно мне непонятен, чего я не скрываю. Написав t=class Вы объявляете тип и естественно не можете присвоить данные типу. Естественно такое компилироваться не будет и я не пытался его компилировать. Вам же не придет в голову писать "t=record X: char; end" и потом обращаться к данным "t.X := #13;". Так что Ваши возражения не принимаю.
Чтобы окончательно снять вопросы приведу пример идентичного объекта реализованного через object и через class

---object-----
type
to=object(TObject)
x:byte
end;
po=^to;
var o:po;
begin
o:=New(po,Init)
o^.x=#13;
Dispose(o,Done)
end

---class-----
type
to=class(TObject)
x:byte
end;
var o:to;
begin
o:=to.Create
o.x=#13;
o.Free
end


Т.е. когда пишется через object есть и объект(to) и ссылка на него (po). Когда пишется через class есть только ссылка(to).
Я думаю, что для Alexander-а я ничего нового не написал, спор имеет чисто теоритический характер, но может кому-то, кто не писал на Паскале 6 или 7, будет интересно.


»»» Palladin (31.07.00 17:40)
Короче, я понял, что объекты в Delphi еще можно использовать. И тут вопрос возник другой. На счет того что имя класса сразу является указателем я понял, но тогда вопрос: можно ли написать класс с нуля или без TObjecta не обойтись?

»»» ASCRUS - ascrus@aport.ru (01.08.00 08:34)
Да ты прав - даже если ты напишешь типа to = class, то все равно это будет означать to = class(TObject). Естественно это сделанно из-за RTTI

»»» SergSuper - sergsuper@mail.ru (01.08.00 09:07)
Если использовать object - то будет без без TObject, чисто твой объект. Если class - то прицепляется автоматом.

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Глюки QReport


Обнаружил, что компонент QReport никак не реагирует на установки принтера PrinterSetup диалога, вызываемого нажатием кнопочкисобственного Preview!
В QuickReport есть собственный объект TQRPrinter, установки которого он использует при печати, а стандартные установки принтеров на него не влияют. В диалоге PrinterSetup, вызываемом из Preview можно лишь выбрать принтер на который нужно печатать (если, конечно, установлено несколько принтеров).

Советую поставить обновление QReport на 2.0J с www.qusoft.com.

Перед печатью (не только из QReport) программно установите требуемый драйвер принтера текущим для Windows





function SetDefPrn(const stDriver : string) : boolean;
begin
SetPrinter(nil).Free;
Result := WriteProfileString('windows', device', PChar( stDriver));
end;


После печати восстановите установки.

НаверхПрислать свои комментарии

Хочу в DLL создать форму, но не модальную, а обыкновенную...


»»» GBF Zero (06.07.00 15:21)
Задача такая: Хочу в DLL создать форму (она уже есть), но не модальную, а обыкновенную. То есть я с ней хочу поработать, а "наработанный" результат (к примеру, число) вернуть в форму, в которой вызывал DLL.

»»» Ilya - lopatkin@ncsp-net.com (07.07.00 11:14)
используй SendMessage. При вызове своей формы (dll) передай ей Handle вызывающей формы. А там обработчик сообщения.

»»» GBF Zero (08.07.00 12:01)
Спасибо Ilya.
Но спасение утопающих - дело рук самих утопающих. Уже разобрался. Тем более, что твой способ мне не подходит.
Я всё реализовал на трёх функция(две DLLе - открытие формы и закрытие, а третья - передача результата). Работает как надо.
Но тебе всё равно спасибо.

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии

Перекодировка текста DOS <-> Widowns <-> Koi8



procedure WinToDos;
var Src, Str:PChar;
begin
Src := Memo1.Lines.GetText; //Берем текст из TMemo как тип PChar
CharToOem(Src, Str); //API функция для перевода текста
Memo2.Lines.Text := StrPas(Str);//Записываем назад
end;

procedure DosToWin;
var Src, Str:PChar;
begin
Src := Memo1.Lines.GetText; //Берем текст из TMemo как тип PChar
OemToChar(Src, Str); //API функция для перевода текста
Memo2.Lines.Text := StrPas(Str);//Записываем назад
end;

var koi8toalt : array [0..127] of char = (
CHR($c4), Chr($b3), Chr($da), Chr($bf),
Chr($c0), Chr($d9), Chr($c3), Chr($b4),
Chr($c2), Chr($c1), Chr($c5), Chr($df),
Chr($dc), Chr($db), Chr($dd), Chr($de),
Chr($b0), Chr($b1), Chr($b2), Chr($f4),
Chr($fe), Chr($f9), Chr($fb), Chr($f7),
Chr($f3), Chr($f2), Chr($ff), Chr($f5),
Chr($f8), Chr($fd), Chr($fa), Chr($f6),
Chr($cd), Chr($ba), Chr($d5), Chr($f1),
Chr($d6), Chr($c9), Chr($b8), Chr($b7),
Chr($bb), Chr($d4), Chr($d3), Chr($c8),
Chr($be), Chr($bd), Chr($bc), Chr($c6),
Chr($c7), Chr($cc), Chr($b5), Chr($f0),
Chr($b6), Chr($b9), Chr($d1), Chr($d2),
Chr($cb), Chr($cf), Chr($d0), Chr($ca),
Chr($d8), Chr($d7), Chr($ce), Chr($fc),
Chr($ee), Chr($a0), Chr($a1), Chr($e6),
Chr($a4), Chr($a5), Chr($e4), Chr($a3),
Chr($e5), Chr($a8), Chr($a9), Chr($aa),
Chr($ab), Chr($ac), Chr($ad), Chr($ae),
Chr($af), Chr($ef), Chr($e0), Chr($e1),
Chr($e2), Chr($e3), Chr($a6), Chr($a2),
Chr($ec), Chr($eb), Chr($a7), Chr($e8),
Chr($ed), Chr($e9), Chr($e7), Chr($ea),
Chr($9e), Chr($80), Chr($81), Chr($96),
Chr($84), Chr($85), Chr($94), Chr($83),
Chr($95), Chr($88), Chr($89), Chr($8a),
Chr($8b), Chr($8c), Chr($8d), Chr($8e),
Chr($8f), Chr($9f), Chr($90), Chr($91),
Chr($92), Chr($93), Chr($86), Chr($82),
Chr($9c), Chr($9b), Chr($87), Chr($98),
Chr($9d), Chr($99), Chr($97), Chr($9a));

function Koi8toWin(const Data:PChar; DataLen :Integer):PChar;
var PCh: PChar;
i: Integer;
begin
PCh:=Data;
for i:=1 to DataLen do
begin
if Ord(Pch^)>127 then Pch^:=koi8toalt[Ord(Pch^)-128];
Inc(PCh);
end;
PCh:=Data;
OemToCharBuff(PCh,PCh,DWORD(DataLen));
Result:=Data;
end;


Спасибо Олегу и Виталию
НаверхПрислать свои комментарии

С каким числовым форматом Delphi работает быстрее всего ?


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

type time, sec
-------------------
single 2.20
double 3.63
real 4.28
extended 5.95
НаверхПрислать свои комментарии

Функции и процедуры для работы с drag-and-drop операциями.


Функции и процедуры для работы с drag-and-drop операциями.

Функция CancelDrag;
Модуль: Controls

Процедура отменяет текущую drag-and-drop или drag-and-dock операцию. Т.е. перетаскивание объекта не происходит.


Функция FindDragTarget( const Pos: TPoint; AllowDisabled: Boolean ): TControl;
Модуль: Controls

Функция возвращает объект базового класса TControl, к которому относится позиция экрана с координатами, определенными параметром Pos. Данная функция используется для определения потенциального получателя drag-and-drop или drag-and-dock операции. Если для указанной позиции не существует никакого оконного средства управления, то функция возвращает nil. Параметр AllowDisabled определяет, будут ли учитываться заблокированные (disabled) объекты.


Функция IsDragObject( Sender: TObject ): Boolean;
Модуль: Controls

Функция определяет, является ли объект, определенный в параметре Sender, потомком класса TDragObject. Данную функцию можно использовать в качестве параметра Source в обработчиках событий OnDragOver и OnDockOver для того, чтобы определить будет ли принят перетаскиваемый объект. Также функцию IsDragObject можно использовать в качестве параметра Source в обработчиках событий OnDragDrop и OnDockDrop для того, чтобы правильно интерпретировать перетаскиваемый объект.
НаверхПрислать свои комментарии

Заставка для программы


Сведения о программе, авторские права и т.д., лучше оформить в виде отдельной формы и показывать ее при запуске программы (как это сделано в Word).
Сделать это не сложно:
1. Создаете форму (например SplashForm).
2. Объявляете ее свободной (availableForms).
3. В Progect Source вставляете следующее (например):




   program Splashin;
   uses
       Forms,
       Main in 'MAIN.PAS',
       Splash in 'SPLASH.PAS'
   {$R *.RES}
   begin
try
       SplashForm := TSplashForm.Create(Application);
       SplashForm.Show;
       SplashForm.Update;
       Application.CreateForm(TMainForm, MainForm);
       SplashForm.Hide;
finally
       SplashForm.Free;
end;
       Application.Run;
   end.



И форма SplashForm держится на экране пока выполняется Create в главной форме. Но иногда она появляется и пропадает очень быстро, поэтому нужно сделать задержку:
1. Добавляете на форму таймер с событием:


procedure TSplashForm.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
end;



2. Событие onCloseQuery для формы:




procedure TSplashForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := Not Timer1.Enabled;
end;

3. И перед SplashForm.Hide; ставите цикл:



repeat
Application.ProcessMessages;
until SplashForm.CloseQuery;


4. Все! Осталось установить на таймере период задержки 3-4 секунды.
5. На последок, у такой формы желательно убрать Caption:
SetWindowLong (Main.Handle,GWL_STYLE, GetWindowLong(Main.Handle, GWL_STYLE) AND NOT WS_CAPTION OR WS_SIZEBOX);


НаверхПрислать свои комментарии

Как сделать так, что при нажатии на Enter происходил переход к следующему элементу формы


Ставите у формы KeyPreview = true и создаете событие KeyPress следующего вида:


procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if (Key = #13) then begin
Key:=#0;
Perform(WM_NEXTDLGCTL,0,0);
end;
end;

НаверхПрислать свои комментарии

Я создал объект TStrings, но при попытке обращения к нему выдается ошибка. В чем проблема?


TStrings -- это абстрактный класс. Вам нужен TStringList.
НаверхПрислать свои комментарии

Прозрачная форма




Эта форма имет прозрачный фон !!!

unit unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
// это просто кнопка на форме - для демонстрации
protected
procedure RebuildWindowRgn;
procedure Resize; override;
public
constructor Create(AOwner: TComponent); override;
end;
var
Form1 : TForm1;
implementation
// ресурс этой формы
{$R *.DFM}

{ Прозрачная форма }
constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
// убираем сколлбары, чтобы не мешались
// при изменении размеров формы
HorzScrollBar.Visible:= False;
VertScrollBar.Visible:= False;
// строим новый регион
RebuildWindowRgn;
end;

procedure TForm1.Resize;
begin
inherited;
// строим новый регион
RebuildWindowRgn;
end;

procedure TForm1.RebuildWindowRgn;
var
FullRgn, Rgn: THandle;
ClientX, ClientY, I: Integer;
begin
// определяем относительные координаты клиенской части
ClientX:= (Width - ClientWidth) div 2;
ClientY:= Height - ClientHeight - ClientX;
// создаем регион для всей формы
FullRgn:= CreateRectRgn(0, 0, Width, Height);
// создаем регион для клиентской части формы
// и вычитаем его из FullRgn
Rgn:= CreateRectRgn(ClientX, ClientY, ClientX + ClientWidth, ClientY +
ClientHeight);
CombineRgn(FullRgn, FullRgn, Rgn, rgn_Diff);
// теперь добавляем к FullRgn регионы каждого контрольного элемента
for I:= 0 to ControlCount -1 do
with Controls[I] do begin
Rgn:= CreateRectRgn(ClientX + Left, ClientY + Top, ClientX + Left +
Width, ClientY + Top + Height);
CombineRgn(FullRgn, FullRgn, Rgn, rgn_Or);
end;
// устанавливаем новый регион окна
SetWindowRgn(Handle, FullRgn, True);
end;
end.


А как Вам понравится эта форма ?

unit rgnu;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Buttons, Menus;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
rTitleBar : THandle;
Center : TPoint;
CapY : Integer;
Circum : Double;
SB1 : TSpeedButton;
RL, RR : Double;
procedure TitleBar(Act : Boolean);
procedure WMNCHITTEST(var Msg: TWMNCHitTest);
message WM_NCHITTEST;
procedure WMNCACTIVATE(var Msg: TWMNCACTIVATE);
message WM_NCACTIVATE;
procedure WMSetText(var Msg: TWMSetText);
message WM_SETTEXT;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

CONST
TitlColors : ARRAY[Boolean] OF TColor =
(clInactiveCaption, clActiveCaption);
TxtColors : ARRAY[Boolean] OF TColor =
(clInactiveCaptionText, clCaptionText);

procedure TForm1.FormCreate(Sender: TObject);
VAR
rTemp, rTemp2 : THandle;
Vertices : ARRAY[0..2] OF TPoint;
X, Y : INteger;
begin
Caption := 'OOOH! Doughnuts!';
BorderStyle := bsNone; {required}
IF Width > Height THEN Width := Height
ELSE Height := Width; {harder to calc if width <> height}
Center := Point(Width DIV 2, Height DIV 2);
CapY := GetSystemMetrics(SM_CYCAPTION)+8;
rTemp := CreateEllipticRgn(0, 0, Width, Height);
rTemp2 := CreateEllipticRgn((Width DIV 4), (Height DIV 4),
3*(Width DIV 4), 3*(Height DIV 4));
CombineRgn(rTemp, rTemp, rTemp2, RGN_DIFF);
SetWindowRgn(Handle, rTemp, True);
DeleteObject(rTemp2);
rTitleBar := CreateEllipticRgn(4, 4, Width-4, Height-4);
rTemp := CreateEllipticRgn(CapY, CapY, Width-CapY, Height-CapY);
CombineRgn(rTitleBar, rTitleBar, rTemp, RGN_DIFF);
Vertices[0] := Point(0,0);
Vertices[1] := Point(Width, 0);
Vertices[2] := Point(Width DIV 2, Height DIV 2);
rTemp := CreatePolygonRgn(Vertices, 3, ALTERNATE);
CombineRgn(rTitleBar, rTitleBar, rTemp, RGN_AND);
DeleteObject(rTemp);
RL := ArcTan(Width / Height);
RR := -RL + (22 / Center.X);
X := Center.X-Round((Center.X-1-(CapY DIV 2))*Sin(RR));
Y := Center.Y-Round((Center.Y-1-(CapY DIV 2))*Cos(RR));
SB1 := TSpeedButton.Create(Self);
WITH SB1 DO
BEGIN
Parent := Self;
Left := X;
Top := Y;
Width := 14;
Height := 14;
OnClick := Button1Click;
Caption := 'X';
Font.Style := [fsBold];
END;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
End;

procedure TForm1.WMNCHITTEST(var Msg: TWMNCHitTest);
begin
Inherited;
WITH Msg DO
WITH ScreenToClient(Point(XPos,YPos)) DO
IF PtInRegion(rTitleBar, X, Y) AND
(NOT PtInRect(SB1.BoundsRect, Point(X,Y))) THEN
Result := htCaption;
end;

procedure TForm1.WMNCActivate(var Msg: TWMncActivate);
begin
Inherited;
TitleBar(Msg.Active);
end;

procedure TForm1.WMSetText(var Msg: TWMSetText);
begin
Inherited;
TitleBar(Active);
end;

procedure TForm1.TitleBar(Act: Boolean);
VAR
TF : TLogFont;
R : Double;
N, X, Y : Integer;
begin
IF Center.X = 0 THEN Exit;
WITH Canvas DO
begin
Brush.Style := bsSolid;
Brush.Color := TitlColors[Act];
PaintRgn(Handle, rTitleBar);
R := RL;
Brush.Color := TitlColors[Act];
Font.Name := 'Arial';
Font.Size := 12;
Font.Color := TxtColors[Act];
Font.Style := [fsBold];
GetObject(Font.Handle, SizeOf(TLogFont), @TF);
FOR N := 1 TO Length(Caption) DO
BEGIN
X := Center.X-Round((Center.X-6)*Sin(R));
Y := Center.Y-Round((Center.Y-6)*Cos(R));
TF.lfEscapement := Round(R * 1800 / pi);
Font.Handle := CreateFontIndirect(TF);
TextOut(X, Y, Caption[N]);
R := R - (((TextWidth(Caption[N]))+2) / Center.X);
IF R < RR THEN Break;
END;
Font.Name := 'MS Sans Serif';
Font.Size := 8;
Font.Color := clWindowText;
Font.Style := [];
end;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
WITH Canvas DO
BEGIN
Pen.Color := clBlack;
Brush.Style := bsClear;
Pen.Width := 1;
Pen.Color := clWhite;
Arc(1, 1, Width-1, Height-1, Width, 0, 0, Height);
Arc((Width DIV 4)-1, (Height DIV 4)-1,
3*(Width DIV 4)+1, 3*(Height DIV 4)+1, 0, Height, Width, 0);
Pen.Color := clBlack;
Arc(1, 1, Width-1, Height-1, 0, Height, Width, 0);
Arc((Width DIV 4)-1, (Height DIV 4)-1,
3*(Width DIV 4)+1, 3*(Height DIV 4)+1, Width, 0, 0, Height);
TitleBar(Active);
END;
end;

end.


НаверхПрислать свои комментарии

Как выдвинуть дверцу CD-ROM'а?


mciSendString('Set cdaudio Door Open Wait', nil, 0, handle);
Также mciSendCommand(mp.DeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);
НаверхПрислать свои комментарии

Обработка событий при работе с клавиатурой


»»» Роман (11.07.00 08:45)
Уважаемые Господа !
Извините за дурацкий вопрос, но может кто подскажет мне, как в Delphi обозначаются буквенные и знаковые (+,-,*,/) клавиши. В литературе нашёл только обозначения F клавиш (VK_F1 и т.д.). Где можно найти ответ на этот вопрос ?

»»» Mike Goblin - mgoblin@mail.ru (11.07.00 09:09)
Дык я делаю так: пишешь какой-нибудь код в OnKeyPressed or OnKeyDown ставишь точку останова и сморишь debuger-ом чего передается в обработчик при нажатии на кнопку

»»» Romych (11.07.00 14:28)
Дааа, радикально, можно проще: ShowMessage(IntToStr(Byte(Key)))

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-

НаверхПрислать свои комментарии

Как написать программу не имеющую ни одной формы?


Создайте новое приложение, затем удалите из проекта все unitы - (Delphi 3 - View - Project Manager)
(Delphi 4 - Project - Remove from project)
Откройте файл проекта
(Delphi 3 - View - Project Source)
(Delphi 3 - Project - View Source)
и отредактируйте его так как приведино ниже.

Пример:

program Project1;

{$R *.RES}

uses SysUtils;

var
f : TextFile;

begin
AssignFile(f, 'TestFile.Txt');
ReWrite(f);
Writeln(f, 'Test');
Close(f);
end.


Источник: Дельфи. Вокруг да около.

НаверхПрислать свои комментарии

Так ли необходимо использовать GetHostByName вместо аналогичного асинхронного метода


Q: Так ли необходимо использовать GetHostByName вместо аналогичного асинхронного метода, если все синхронные методы сильно грузят процессор и их трудно прервать в случае необходимости, только через TerminateThread. Я тут обрадовался советам, написал кэш имен и ip адресов, сделал через GetHostByName, прилепил нотификации, многопоточность, а оказывается, все опять нужно переделывать? Или оставить как есть? Дело в том, что я это, несомненно буду использовать в последующих разработках, и мне хочется делать сразу на совесть. Дайте совет, please. Я проверял, все это хозяйство вроде процессор грузит достаточно мало.


A: Ты прав, никакой нагрузки на процессор нет. Пример тому - AMV и ADR (см. подпись), многопоточные программы, использующие только berkley-подмножество WinSocks 1.1, никаких асинхронных функций. Каждое письмо посылается и каждый емайл проверяется отдельным потоком. Прерывать при помощи TerminateThread тоже не надо. Когда мне нужно остановить поток (пользователь остановил проверку адресов), я делаю так:

1). устанавливаю int network_off = true

2). из главного потока делаю shutdown и closesocket для сокета потока - даже
если я висел на recv или send, то они увидев это вывылятся

3). в коде потока часто-часто стоят проверки переменной network_off и если
true, то поток __самостоятельно__ и цивилизовано завершается, если он не
соизволит остановится увидев "ошибку сети"

4). главный поток ждет 500 мс и считает сколько осталось потоков, если
потоки завершились не все, то он ждет еще 500 ms т повторяет операцию, лишь
за тем он вызывает для непокорных потоков TerminateThread

На самом деле пункт 4 немного похитрей ;), но идея такая. Потоки мне убивать
практически никогда не приходится.

Alexander P. Gorlach,
Elcom E-mail Management Software Team:
* Advanced Mail List Verify: http://www.elcomsoft.com/amv.html
* Advanced Direct Remailer: http://www.elcomsoft.com/adr.html
НаверхПрислать свои комментарии

CustomDraw в TListView


»»» Merle Corey (03.07.00 11:43)
Не подскажет ли кто-нибудь где взять примеры реализации OnCustomDraw, OnCustomDrawItem и OnCustomDrawSubItem (в частности очень важно последнее)

»»» kingdom - kingdom@tepkom.ru (09.07.00 18:46)
В Дельфях5.0 есть пример VirtualListView, где используется все выше перечисленное...

-= Из конференции сайта MASTERS OF DELPHI (http://delphi.mastak.com) =-
НаверхПрислать свои комментарии


Сайт клуба любителей Delphi - Masters of Delphi
Designed by MoveR Studio © 2000  - | -  Вопросы? Предложения? пишите