Текущий архив: 2005.12.18;
Скачать: CL | DM;
ВнизОтслеживание события из функции. Найти похожие ветки
← →
MasterVovan (2005-11-30 15:28) [0]Здравствуйте!
Как сделать так, чтобы остановить работу функции до тех пор, пока не произойдет событие какого либо компонента, затем продолжить выполнение этой функции?
Заранее спасибо!
С уважением!
← →
Владислав © (2005-11-30 15:41) [1]Знать бы ситуацию подробнее, можно было бы советовать...
А так, на вскидку, есть только "ореховый" пример :)
← →
ANB © (2005-11-30 15:42) [2]
> MasterVovan (30.11.05 15:28)
Изгал какой. Но можно.
while (проверка флага, который выставит обработчик события компонента) do begin
Application.ProcessMessages;
Sleep(50);
end;
Для некоторых событий не поможет.
← →
MasterVovan (2005-11-30 15:48) [3]=) орехового не надо...
А ситуация такая... Есть длл, в ней есть функция определения определения smtp relay из dns... Собственно она и запускается из приложения, на выходе должна получить relay... Так вот... Для определения этого релэя запускаю метод компонента DNS-ресолвинга. По окончанию ресолвинга происходит событие OnRequestDone, которого я и должен ждать из функции, и когда оно произойдет, считать нужный релэй и вернуть в приложение...
ну вот... типа того... =) так понятнее?
← →
MasterVovan (2005-11-30 15:51) [4]2ANB:
интересный вариант... попробую... но че-то как-то не очень мне нравится... =)
А какие нибудь еще есть способы решения? Пробовал уже на форму пихать этот компонент, все работает, но не знаю как форму скрыть... =)
← →
Владислав © (2005-11-30 15:52) [5]TDataModule?
← →
MasterVovan (2005-11-30 16:02) [6]2Владислав:
хм... =) не слышал о таком чуде еще пока... но глянув в хелп, понял, что это может быть то что надо... надо только разобраться как его использовать на мое благо... =) Не имеется ли случаянно каких нить примерчиков?
← →
MasterVovan (2005-11-30 16:14) [7]Снова вопрос... Почитал про TDataModule но так и не понял, как его применить в моем случае... Как его можно запустить так, чтоб он как модальная форма приостанавливал выполнение функции до выхода из него?
← →
Владислав © (2005-11-30 16:20) [8]
> Для определения этого релэя запускаю метод компонента DNS-
> ресолвинга. По окончанию ресолвинга происходит событие OnRequestDone
"метод компонента DNS- ресолвинга" выполняется асинхронно?
← →
MasterVovan (2005-11-30 16:49) [9]2Владислав:
Я так понял что да...
← →
DiamondShark © (2005-11-30 16:53) [10]Разбить функцию на две.
Вызвать первую.
Дождаться события.
Вызвать вторую.
← →
MasterVovan (2005-11-30 16:56) [11]2DiamondShark:
в том то и дело что нельзя... функцию вызывает из длл приложение, и если ее завершить то приложение ответа от других уже не получит....
← →
ANB © (2005-11-30 17:12) [12]
> MasterVovan (30.11.05 16:56) [11]
Если из ДЛЛ, то Application лучше не использовать. Тогда только sleep. Если не хочешь, чтобы основное приложение подвисало - тогда выноси вызов функции в отдельный поток. А зачем эту функцию в ДЛЛ то пихать ?
← →
MasterVovan (2005-11-30 17:34) [13]2ANB:
> А зачем эту функцию в ДЛЛ то пихать ?
Просто есть набор программ, которые будут использовать данную функцию, не охота в каждую прописывать ее...
> Если из ДЛЛ, то Application лучше не использовать.while флаг do
begin
Sleep(50);
end;
так оно будет?
> Если не хочешь, чтобы основное приложение подвисало - тогда выноси вызов функции в отдельный поток.
это то понятно, но не принципиально...
← →
MasterVovan (2005-11-30 17:45) [14]2ANB:
как и ожидалось при таком варианте:while флаг do
begin
Sleep(50);
end;
все зависает в вечном цикле...
← →
Reindeer Moss Eater © (2005-11-30 17:53) [15]А ты конечно же ждал чуда, смотря на этот код?
← →
MasterVovan (2005-11-30 18:04) [16]2Reindeer Moss Eater:
Можно и так сказать... просто перепробовав тучу вариантов я уже не гнушаюсь заведомо не рабочими, как говорится "а мало ли"...
← →
alex_*** © (2005-11-30 18:52) [17]я думаю чтоб ловить события, надо на них подписаться - обработчик свой впихнуть куда-ть. Можно у формы или у нужных компонентов перекрыть WndProc. Вот вопрос: как ты хотел ждать и одновременно чтоб какой-то компонент работал-генерил события? Отдельный поток только если
← →
MasterVovan (2005-11-30 19:16) [18]2alex_***:
Как организовать поток, в котором будет находиться этот компонент со своими событиями?
← →
alex_*** © (2005-11-30 19:25) [19]компонент-то будет находится в основном потоке, вот где ты будешь с ожиданием находится, это вопрос... Тебе это действительно нужно? Может без этого? Потоки это не так просто
← →
MasterVovan (2005-11-30 19:49) [20]2alex_***:
к сожалению, очень... возможен вариант с формой, которую буду открывать модально (как было в самом начале и работало), но как тогда сделать чтоб ее на экране небыло и кнопок внизу никаких не появлялось? какуюнибудь виртуальную форму надо, невидимую... =)
← →
alex_*** © (2005-11-30 19:54) [21]ну вы блин даете... невидимую модальную форму. ЧТоб заблокировать экран? Честно извратами не занимался никогда. и желания даже нет. За них мне деньги не платят ;)
← →
MasterVovan (2005-11-30 20:04) [22]2alex_***:
блокирование основного приложения происходит на 1 секунду максимум, ибо процесс поиска mx записей не долог... Просто когда ипользую видимую форму, тогда это окно мигнет на 1 секунду не прочитать на ней ничего и не понять что это... Ощущение что глюк, который вылез, а я его отловил и закрыл, чтоб никто не понял... А мне это начальству нести и в глаза смотреть...
← →
Набережных С. © (2005-11-30 20:35) [23]Callback?
Или в функции запустить метод компонента и ждать эвента, который компонент установит по событию. Или, как уже сказал alex_*** ©, метод запускать в доп.потоке, если ему требуется цикл выборки сообщений - чтобы не мешать работе хоста.
В общем, надо знать, как работает компонент.
← →
MasterVovan (2005-11-30 21:09) [24]Вот думал тут думал... Приглядел такую вещь как сервис... а что если в нем запускать? какие будут мнения?
← →
Владислав © (2005-12-01 09:31) [25]
> MasterVovan (30.11.05 21:09) [24]
Что, для функции сервис писать?
У компонента случайно нет свойства аснихронный/синхронный?
Еще вариант :) , подсмотреть реализацию нужной функции в компоненте, написать свою, синхронную.
← →
alex_*** © (2005-12-01 09:36) [26]кстати на событии OnIdle можно проверять некий флаг, который будет выставлять наблюдаемый объект. Только обработка этого события может отложиться ненамного, в зависимости от загрузки приложения. Ты еще раз на пальцах расскажи задачу, у меня такое впечатление что можно без извратов обойтись
← →
alex_*** © (2005-12-01 10:30) [27]что за св-ва синхронный\асинхронный? Как кнопка может быть асинхр. ?
← →
Владислав © (2005-12-01 11:45) [28]А при чем здесь кнопка вообще?
MasterVovan использует компонент, я про него и спрашиваю.
← →
alex_*** © (2005-12-01 11:49) [29]и кнопка компонент
← →
Владислав © (2005-12-01 12:03) [30]По-моему, из [8] и [9] ясно, о чем речь идет. Так при чем здесь кнопка???
← →
alex_*** © (2005-12-01 12:10) [31]ты прав. не читал вчера внимательно. а разве "функция определения определения smtp relay из dns" асинхронно запускается?
← →
MasterVovan (2005-12-01 12:14) [32]Значит так... задача такая:
есть адрес dns сервера есть адрес сайта. надо выцепить mx записи от туда. Выцепить не проблема, это все работает, все отлажено.
Проблема вот в чем: необходимо создать dll в которой будет находиться эта функция. Когда вызывается функция ей передаются необходимые параметры (адрес dns сервера есть адрес сайта), вернуть должна mx запись. Загрузив параметры в функцию, присваиваем их соответствующим свойствам компонента (ICS DNSQuery) и вызываем метод компонента (MXLookup). По завершению поиска mx записи происходит событие onDnsRequestDone, где необходимо считать найденные mx записи. Но функция к сожалению не ждет этого события и происходит выход... В результате никаких mx записей не получаем.
задача решается с помощью модальной формы, которую запускаем (тем самым приостанавливая работу функции до закрытия формы) и на которой находится данный компонент и при нужном событии (onDnsRequestDone) ее закрывает, получив при этом желанную mx запись. и соответстевенно завершаем нажу функцию возвращением того, чего искали...
все бы ничего, но эта модальная форма выскакивая на 1 секунду сооздает впечатление глюка...
приведу даже реализацию =)
==================================
findsmtp.dll
==================================library Project1;
uses
SysUtils,
Classes,
Unit1 in "Unit1.pas" {SMTP_Searching_Form};
{$R *.res}
function getsmtp(dns_a,smtpa: PChar): PChar; stdcall;
begin
SMTP_Searching_Form := TSMTP_Searching_Form.Create(nil);
dns_adr:=String(dns_a);
smtp_adr:=String(smtpa);
SMTP_Searching_Form.ShowModal;
result:=PChar(smtpserv);
SMTP_Searching_Form.Free;
end;
exports getsmtp;
begin
end.
----------------------unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DnsQuery, ExtCtrls, StdCtrls, SyncObjs;
type
TSMTP_Searching_Form = class(TForm)
Dns: TDnsQuery;
Label1: TLabel;
Bevel1: TBevel;
procedure DnsRequestDone(Sender: TObject; Error: Word);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
SMTP_Searching_Form: TSMTP_Searching_Form;
dns_adr,smtp_adr,smtpserv: string;
implementation
{$R *.dfm}
procedure TSMTP_Searching_Form.DnsRequestDone(Sender: TObject;
Error: Word);
begin
smtpserv:=dns.MXExchange[0];
close;
end;
procedure TSMTP_Searching_Form.FormShow(Sender: TObject);
begin
DNS.CleanupInstance;
dns.Port:="53";
dns.Addr:=dns_adr;
dns.Proto:="udp";
dns.MultiThreaded:=true;
dns.MXLookup(smtp_adr);
end;
end.
==================================
пример использования
==================================unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
Edit2: TEdit;
Button1: TButton;
Edit3: TEdit;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function getsmtp(dns,smtpa: PChar): PChar; stdcall; external "FINDSMTP.DLL";
procedure TForm1.Button1Click(Sender: TObject);
begin
edit3.Text:=String(getsmtp(PChar(Edit1.Text),PChar(Edit2.Text)));
end;
end.
← →
alex_*** © (2005-12-01 12:41) [33]а в варианте с циклом, как у тебя флаг проставлялся?
← →
alex_*** © (2005-12-01 12:53) [34]может что-то типа того?
TOnDone=class
public
OK: Boolean;
procedure DnsRequestDone(Sender: TObject; Error: Word);
Begin
OK := true;
End;
end;
implementation
function getsmtp(dns_a,smtpa: PChar): PChar; stdcall;
begin
Obj := TOnDone.Create();
Dns := TDnsQuery.Create(nil);
try
Dns.OnDnsRequest := Obj.OnDone;
dns.Port:="53";
dns.Addr:=dns_adr;
dns.Proto:="udp";
dns.MultiThreaded:=true;
dns.MXLookup(smtp_adr);
whikle (not Obj.OK)
Begin
appl.ProcessMessages();
Sleep(100);
End;
finally
Obj.Free();
dns.Free();
end
end;
← →
Digitman © (2005-12-01 12:53) [35]непонятно, на кой ляд здесь вообще нужна эта самая форма ...
← →
MasterVovan (2005-12-01 13:09) [36]если этот цикл:
while флаг do
begin
Application.ProcessMessages;
Sleep(50);
end;
то dll не знает слова Application, так как скорей всего это не application... =)
а если:while флаг do
begin
Sleep(50);
end;
то устанавливаю перед запуском запуском метода MXLookup в true и сбрасываю при событии DnsRequestDone.
← →
MasterVovan (2005-12-01 13:13) [37]2alex_***:
сейчас попробую...
2Digitman:
так вот как раз и не нужна! =) вот как избачить ищем варианты...
← →
MasterVovan (2005-12-01 13:16) [38]2alex_***:
ну вот не хочет знать компилятор слов appl и application... =(
← →
alex_*** © (2005-12-01 13:41) [39]ну appl он, конечно, и не будет знать. чтобы понимал Aplication, надо Forms в uses поставить. Проверь на nil Application перед использованием. У тебя длл с runtime пакетами или без?
← →
MasterVovan (2005-12-01 14:22) [40]=)))) всё! я спасён!!!
===========================library Project1;
uses
SysUtils,
Classes,
DnsQuery,
forms;
{$R *.res}
type
TOnDone=class
public
OK: Boolean;
procedure DnsRequestDone(Sender: TObject; Error: Word);
end;
procedure TOnDone.DnsRequestDone(Sender: TObject; Error: Word);
Begin
OK := true;
End;
function getsmtp(dns_a,smtpa: PChar): PChar; stdcall;
var
Dns: TDnsQuery;
Obj: TOnDone;
begin
Obj := TOnDone.Create();
Dns := TDnsQuery.Create(nil);
try
Dns.OnRequestDone := Obj.DnsRequestDone;
dns.Port:="53";
dns.Addr:=dns_a;
dns.Proto:="udp";
dns.MultiThreaded:=true;
dns.MXLookup(smtpa);
while (not Obj.OK) do
Begin
application.ProcessMessages();
Sleep(100);
End;
result:=PChar(dns.MXExchange[0]);
finally
Obj.Free();
dns.Free();
end;
end;
exports getsmtp;
begin
end.
=====================
полностью рабочий вариант без всяких дополнительных форм и модулей!!! =)
Огромное спасибо за помощь!
PS: проверил на nil application, но оказался не nil. А вообще возможно обратное?
← →
alex_*** © (2005-12-01 14:43) [41]Наверно нет. На 5-ке какие-то траблы были... не помню.
← →
MasterVovan (2005-12-01 14:54) [42]ясно... 5-ку не использовал.. сразу с 4-ки на 6-ку перескочил... =)
еще раз спасибо!
PS: не совсем тема для новичков оказалась... ;)
← →
Набережных С. © (2005-12-01 16:29) [43]
> PS: не совсем тема для новичков оказалась... ;)
Ошибаешься
Страницы: 1 2 вся ветка
Текущий архив: 2005.12.18;
Скачать: CL | DM;
Память: 0.56 MB
Время: 0.015 c