Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Событие/сообщение в DLL, автоматически обрабатываемое в main [D6, Win95/98, WinXP]


bvn123 ©   (2006-08-16 17:47:00) 

Здравствуйте.
Хочу в DLL организовать событие ev=TEvent по окончании приема данных, в основную программу передавать, например, ev.handle. Как организовать в осн.программе обработчик события, имея handle, без явного написания цикла не знаю.

Получается, что такая организация не будет отличаться от следующей: установки флага в DLL, после считывания в цикле установленного флага его сброс (такой вариант сделан).

Пробую передавать и принимать Windows Message в простой программе
сообщение Wm_Form обрабатывается (обработчик объявлен в TForm1=class(TForm)), сообщение Wm_Ev нет (обработчик объявлен в TMyEv=class(TObject)).
Подскажите, пожалуйста, в чем ошибка? Спасибо.


unit UEvent;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls, Spin;

const   WM_Form = WM_USER + 300;
       WM_ev   = WM_USER + 301;
type
 TMyEv = class(TObject)
 public
    procedure WmEv(var Msg: TMessage); message WM_ev;
 end;

 TForm1 = class(TForm)
   memo: TMemo;
   se: TSpinEdit;
   Timer1: TTimer;
   procedure Timer1Timer(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
    procedure WmReady(var Msg: TMessage); message WM_Form;
 public
   ev:TMyEv;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin
se.Value:=se.Value+1;
if se.Value mod 10=0 then PostMessage(Handle, WM_Form, 0, 0);
if se.Value mod 23=0 then PostMessage(Handle, WM_ev, 0, 0);
end;

procedure TForm1.WmReady(var Msg: TMessage);
begin
Form1.memo.Lines.Strings[0]:=Form1.memo.Lines.Strings[0]+'f';
end;

procedure TMyEv.WmEv(var Msg: TMessage);
begin
Form1.memo.Lines.Strings[0]:=Form1.memo.Lines.Strings[0]+'e';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.ProcessMessages;
ev:=TMyEv.Create;
end;

end.


Сергей М.   (2006-08-21 09:13:00) [1]


> подозреваю, что в dll организован поток


Ну и что ?
Чем плох колбэк в доп.потоке ?


Наиль   (2006-08-18 13:06:00) [2]


> А callback чем не устраивает ?

Я подозреваю, что в dll организован поток, иначе достаточно было бы дождаться завершения процедуры из dll (в моём примере Run). В таком случае PostMessage выгоднее.


Ketmar   (2006-08-18 13:04:00) [3]

> [8] bvn123   (18.08.06 12:57)
памяти не жалко? и ресурсов?


Наиль   (2006-08-18 13:03:00) [4]

Если написать так:
PostMessage(Application.handle, WM_ev, 0, 0);
а приём организовать через Application.HookMainWindow, то вторая форма не понадобится.
Application.HookMainWindow - регистрирует твою процедуру, которая должна обрабатывать сообщения приходящие приложению (Application)


Сергей М.   (2006-08-18 13:01:00) [5]

А callback чем не устраивает ?


bvn123   (2006-08-18 12:57:00) [6]

Еще раз спасибо за подсказку,
создал вторую форму с visible:=false, передавая сообщение ей:
PostMessage(Form2.handle, WM_ev, 0, 0);
Обработчик сообщения функционирует.


clickmaker   (2006-08-18 12:29:00) [7]


> Пытаюсь организовать сообщение или событие для объекта без
> визуального отображения

тогда в корне не верно использовать PostMessage, поскольку она работает только для окон.
Если у тебя есть невизуальный объект, то либо напрямую к нему обращайся либо организуй поток с циклом выборки сообщений PeekMessage или GetMessage. А отправить сообщение потоку можно через PostThreadMessage


bvn123   (2006-08-18 12:26:00) [8]

Спасибо за ответы.
Попробую разобраться с предложением Наиля.

Clickmaster: "а зачем тебе отдельный объект, если ты в нем все равно обращаешься к Form1.memo.Lines?"
Пытаюсь организовать сообщение или событие для объекта без визуального отображения (без окна), обращаюсь к Form1.memo лишь для индикации того, что обработка сообщения произошла.

Сергей М:"Сообщение ты посылаешь окну формы, а принимать и обрабатывать его почему-то должен совсем другой объект, к тому же вообще не создающий окна."
Попробую использовать визуальный компонент, например, TPanel со свойством visible:=false, с передачей сообщения ему, если не выйдет - новую форму, также с visible:=false

Спасибо.


Наиль   (2006-08-17 13:54:00) [9]

Как вариант.
К примеру, функция Run должна активировать передачу данных и сообщить о завершении, тогда лучше её оформить так:
procedure Run(EventProc:TEventProc);
здесь
TEventProc=procedure(Handle:THandle);
Работа будет выглядеть так:
procedure Event(Handle:THandle);
begin
что-нибудь
end;

begin
...
Run(Event)
...
end;


соответственно, cам Run будет выглядеть так:
procedure Run(EventProc:TEventProc);
begin
Передача данных
EventProc(1);
end;


В качестве второго способа, могу предложить обратить внимание на
Application.HookMainWindow в сочетании с Application.Handle


Сергей М.   (2006-08-17 08:22:00) [10]


> bvn123   (16.08.06 18:17) [2]


> PostMessage(Handle, WM_ev, 0, 0);


Сообщение ты посылаешь окну формы, а принимать и обрабатывать его почему-то должен совсем другой объект, к тому же вообще не создающий окна.
И как понимать это ?


clickmaker   (2006-08-16 18:24:00) [11]

а зачем тебе отдельный объект, если ты в нем все равно обращаешься к Form1.memo.Lines?


bvn123   (2006-08-16 18:17:00) [12]

цитата:
clickmaker ©   (16.08.06 18:06) [1]
у TObject нет цикла обработки сообщений

Посоветуйте, как изменить листинг?
вместо TObject пробовал TComponent и TControl - результат тот же


clickmaker   (2006-08-16 18:06:00) [13]

у TObject нет цикла обработки сообщений


Наверх

Титульная страница Поиск, карта сайта Написать письмо