![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Отслеживание события из функции.
MasterVovan © (2005-11-30 15:28:00)Здравствуйте!
Как сделать так, чтобы остановить работу функции до тех пор, пока не произойдет событие какого либо компонента, затем продолжить выполнение этой функции?
Заранее спасибо!
С уважением!
Набережных С. (2005-12-01 16:29:00) [1]
> PS: не совсем тема для новичков оказалась... ;)
Ошибаешься
MasterVovan (2005-12-01 14:54:00) [2]ясно... 5-ку не использовал.. сразу с 4-ки на 6-ку перескочил... =)
еще раз спасибо!
PS: не совсем тема для новичков оказалась... ;)
alex_*** (2005-12-01 14:43:00) [3]Наверно нет. На 5-ке какие-то траблы были... не помню.
MasterVovan (2005-12-01 14:22:00) [4]=)))) всё! я спасён!!!
===========================
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 13:41:00) [5]ну appl он, конечно, и не будет знать. чтобы понимал Aplication, надо Forms в uses поставить. Проверь на nil Application перед использованием. У тебя длл с runtime пакетами или без?
MasterVovan (2005-12-01 13:16:00) [6]2alex_***:
ну вот не хочет знать компилятор слов appl и application... =(
MasterVovan (2005-12-01 13:13:00) [7]2alex_***:
сейчас попробую...
2Digitman:
так вот как раз и не нужна! =) вот как избачить ищем варианты...
MasterVovan (2005-12-01 13:09:00) [8]если этот цикл:
while флаг do
begin
Application.ProcessMessages;
Sleep(50);
end;
то dll не знает слова Application, так как скорей всего это не application... =)
а если:
while флаг do
begin
Sleep(50);
end;
то устанавливаю перед запуском запуском метода MXLookup в true и сбрасываю при событии DnsRequestDone.
alex_*** (2005-12-01 12:53:00) [9]может что-то типа того?
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:00) [10]непонятно, на кой ляд здесь вообще нужна эта самая форма ...
alex_*** (2005-12-01 12:41:00) [11]а в варианте с циклом, как у тебя флаг проставлялся?
MasterVovan (2005-12-01 12:14:00) [12]Значит так... задача такая:
есть адрес 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:10:00) [13]ты прав. не читал вчера внимательно. а разве "функция определения определения smtp relay из dns" асинхронно запускается?
Владислав (2005-12-01 12:03:00) [14]По-моему, из [8] и [9] ясно, о чем речь идет. Так при чем здесь кнопка???
alex_*** (2005-12-01 11:49:00) [15]и кнопка компонент
Владислав (2005-12-01 11:45:00) [16]А при чем здесь кнопка вообще?
MasterVovan использует компонент, я про него и спрашиваю.
alex_*** (2005-12-01 10:30:00) [17]что за св-ва синхронный\асинхронный? Как кнопка может быть асинхр. ?
alex_*** (2005-12-01 09:36:00) [18]кстати на событии OnIdle можно проверять некий флаг, который будет выставлять наблюдаемый объект. Только обработка этого события может отложиться ненамного, в зависимости от загрузки приложения. Ты еще раз на пальцах расскажи задачу, у меня такое впечатление что можно без извратов обойтись
Владислав (2005-12-01 09:31:00) [19]
> MasterVovan (30.11.05 21:09) [24]
Что, для функции сервис писать?
У компонента случайно нет свойства аснихронный/синхронный?
Еще вариант :) , подсмотреть реализацию нужной функции в компоненте, написать свою, синхронную.
MasterVovan (2005-11-30 21:09:00) [20]Вот думал тут думал... Приглядел такую вещь как сервис... а что если в нем запускать? какие будут мнения?