Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2005.12.18;
Скачать: [xml.tar.bz2];

Вниз

Отслеживание события из функции.   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.021 c
2-1133245363
Andry
2005-11-29 09:22
2005.12.18
Фокус бутона


14-1133154091
Antonn
2005-11-28 08:01
2005.12.18
Поздравьте меня, у меня сестренка родилась!


5-1116963546
w666w
2005-05-24 23:39
2005.12.18
Как в TListItem отрисовать TSpinEdit?


14-1133248465
dr D
2005-11-29 10:14
2005.12.18
Что-то вы тут завели: политика, политика ...


2-1133440242
Alexey Panov
2005-12-01 15:30
2005.12.18
почта и Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский