Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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. А вообще возможно обратное?



Страницы: 1 2 вся ветка

Текущий архив: 2005.12.18;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.042 c
2-1133393751
Юрий Ж.
2005-12-01 02:35
2005.12.18
[?]TClientSocket & TServerSocket


4-1129557047
idx
2005-10-17 17:50
2005.12.18
рабочий стол с панелью инструментов


8-1121438062
Kerk
2005-07-15 18:34
2005.12.18
Screen Mate


14-1132954799
dior
2005-11-26 00:39
2005.12.18
я не могу написать тест на делфи(((


2-1133721142
LordPZ
2005-12-04 21:32
2005.12.18
Хочу сделать, но не знаю как.