Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Компоненты Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.07.2009, 02:41   #1
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию как правильно компонент может повесить Хук на сообщения(родителя/приложения)

Код:
constructor TPcBeholderRC.Create(AOwner:TComponent);
begin
 inherited Create(AOwner);
 FTime:=50;
 if not(csDesigning in ComponentState) then
  begin
   Application.HookMainWindow(HookAppProc);
   if Owner is TWinControl then HookForm;
   if Owner is TWinControl
    then RCThread:=TRCThread.Create(true,(Owner as TWinControl).Handle,FTime)
    else RCThread:=TRCThread.Create(true,Application.Handle,FTime);
  end;
end;

procedure TPcBeholderRC.HookFormProc(var Msg: TMessage);
begin
 if Msg.Msg<>WM_RC then begin Msg.Result:=CallWindowProc(OldWndProc,(Owner as TWinControl).Handle,Msg.Msg,Msg.wParam,Msg.lParam);exit;end;
 case Msg.WParam of
  RC_KEYDOWN:if assigned(FOnKeyDown) then FOnKeyDown(Self,Msg.LParam);
  RC_KEYUP:if assigned(FOnKeyUp) then FOnKeyUp(Self,Msg.LParam);
  RC_KEYPRESS:if assigned(FOnKeyPress) then FOnKeyPress(Self,Msg.LParam);
  else Msg.Result:=CallWindowProc(OldWndProc,(Owner as TWinControl).Handle,Msg.Msg,Msg.wParam,Msg.lParam);
 end;
end;

procedure TPcBeholderRC.HookForm;
begin
 if (Owner as TWinControl)<>nil then
  begin
   OldWndProc:=Pointer(GetWindowLong((Owner as TWinControl).Handle,GWL_WNDPROC));
{$IFDEF DELPHI_6_UP}
   NewWndProc:=Classes.MakeObjectInstance(HookFormProc);
{$ELSE}
   NewWndProc:=MakeObjectInstance(HookFormProc);
{$ENDIF}
   SetWindowLong((Owner as TWinControl).Handle,GWL_WNDPROC,LongInt(NewWndProc));
  end;
end;

procedure TPcBeholderRC.UnhookForm;
begin
 if ((Owner as TWinControl)<>nil)and(Assigned(OldWndProc)) then
  SetWindowLong((Owner as TWinControl).Handle,GWL_WNDPROC,LongInt(OldWndProc));
 if Assigned(NewWndProc) then
{$IFDEF DELPHI_6_UP}
  Classes.FreeObjectInstance(NewWndProc);
{$ELSE}
  FreeObjectInstance(NewWndProc);
{$ENDIF}
 NewWndProc:=nil;
 OldWndProc:=nil;
end;

function TPcBeholderRC.HookAppProc(var Msg:TMessage):Boolean;
begin
 Result:=false;
 if Msg.Msg<>WM_RC then begin {Result:=true;}exit;end;
 case Msg.WParam of
  RC_KEYDOWN:if assigned(FOnKeyDown) then FOnKeyDown(Self,Msg.LParam);
  RC_KEYUP:if assigned(FOnKeyUp) then FOnKeyUp(Self,Msg.LParam);
  RC_KEYPRESS:if assigned(FOnKeyPress) then FOnKeyPress(Self,Msg.LParam);
 end;
end;
вот пытался сделать...но не получилось ничего...то есть мои сообщения не обрабатываются


или проще компоненту получать Хендл и уже обрабатывать сообщения?
(компонент не визуальный)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 09.07.2009 в 03:17.
Пепел Феникса вне форума Ответить с цитированием
Старый 09.07.2009, 08:27   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
SetWindowLong((Owner as TWinControl).Handle,GWL_WNDPROC,Lon gInt(NewWndProc));
А если просто переопределить процедуру WindowProc у родителя?

т.е. я имел ввиду вот что-то типа такого:
Код:
unit Unit1;

interface

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

type
 TListBox=class(StdCtrls.Tlistbox)
 public
  wndp:TWndMethod;
  procedure ppp (var Message: TMessage);
 end;
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public       lb:TListBox;
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TListBox }

procedure TListBox.ppp(var Message: TMessage);
begin
//
 Items.Add(inttostr(Message.Msg));
 wndp(Message);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  lb:=TListBox.Create(form1);
  with lb do begin
  top:=10;left:=10;width:=100;Height:=400;
  Parent:=self;
  Show;
  wndp:=Parent.WindowProc;
  Parent.WindowProc:=ppp;
  end;
end;

end.
P.S. Так давно не писал компоненты, что аж сам заинтересовался
I'm learning to live...

Последний раз редактировалось Stilet; 09.07.2009 в 08:46.
Stilet вне форума Ответить с цитированием
Старый 12.07.2009, 00:51   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Извиняюсь что долго не отвечал...Стилет, а кто меня пустит в protected секцию?

я нашел уже ошибку...я директивы перепутал(overload, а надо override)
потому конструктор и не работал(исключение динамическое создание)
+переделал немного обработчик событий

в общем тема закрыта.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно установить компонент? Alex Cones Компоненты Delphi 1 28.04.2009 21:38
Как правильно использовать компонент TDBF SadStar Компоненты Delphi 0 27.03.2009 02:48
как повесить на кнопку 2 действия??? Только_Учусь Общие вопросы Delphi 4 22.09.2008 19:42
Как "Ловить" сообщения приложения? Air Win Api 5 26.02.2008 19:26
Как поменять родителя компонента? Avron Общие вопросы Delphi 3 02.10.2007 16:47