Как заставить Lazarus выдавать все сообщ. в WndProc?
Модератор: Модераторы
Как заставить Lazarus выдавать все сообщ. в WndProc?
В общем, не знаю кому из разработчиков Lazarus пришла идея о блокировании сообщений ОСИ, такие как: WM_NCHITTEST и другие, наверно причина была, но дело в том что под целевую ось это резко ограничивает возможности разработки, а то и вообще делает невозможным реализовать, те или иные специфичные вещи.
Вопрос в том как вернуть все сообщения которые шлет ОС обратно в оконную процедуру, чтоб можно было нормально их обрабатывать?
Вопрос в том как вернуть все сообщения которые шлет ОС обратно в оконную процедуру, чтоб можно было нормально их обрабатывать?
Последний раз редактировалось .wOvAN 18.07.2010 22:37:00, всего редактировалось 2 раза.
Re: Как заставить Lazarus выдавать все сообщения в WinProc?
да их и не убирал никто. просто до виндовых сообщений в лазарусе добраться не так просто, они живут на уровне специфичных виджетсетов. но зато в лазарусе появились сообщения самой LCL, которые виджетсеты сами транслируют в вызовы нужных интерфейсов. они не совсем такие, как вы привыкли в винде, но 99% потребностей покрывают с лихвой. просто откройте и посмотрите на модуль LMessages.
по фактам. для основного окна пишете:
для компонентов - как и в дельфи, наследуетесь от комонента, переопределяете нужные события.
Добавлено спустя 2 минуты 25 секунд:
кстати, там же найдёте и ваш

по фактам. для основного окна пишете:
Код: Выделить всё
TForm1 = class(TForm)
protected
procedure WMLButtonDown(var Message: TLMLButtonDown); message LM_LBUTTONDOWN;
private
{ private declarations }
public
{ public declarations }
end;
...
procedure TForm1.WMLButtonDown(var Message: TLMLButtonDown);
begin
Memo1.Lines.Add (TimeToStr (Message.Msg) + ' ' + IntToStr(Message.Pos.X) + ' ' + IntToStr(Message.Pos.Y));
end;
для компонентов - как и в дельфи, наследуетесь от комонента, переопределяете нужные события.
Добавлено спустя 2 минуты 25 секунд:
кстати, там же найдёте и ваш
Код: Выделить всё
//-------------
// Messages
//-------------
..
LM_NCHITTEST = $0084;
Re: Как заставить Lazarus выдавать все сообщения в WinProc?
На счет переименования я в курсе. Но от переименования названий ничего не меняется, а в эти 99.9% не попадает нужное. И событие ...HITTEST и многие другие не попадают.
Пишите как угодно:
procedure LMHittest(var Message: TLMHittest); message LM_HITTEST;
никогда не возникнет.
Пишите как угодно:
procedure LMHittest(var Message: TLMHittest); message LM_HITTEST;
никогда не возникнет.
- Alexx2000
- постоялец
- Сообщения: 490
- Зарегистрирован: 25.10.2006 00:22:07
- Откуда: Мытищи
- Контактная информация:
Re: Как заставить Lazarus выдавать все сообщения в WinProc?
.wOvAN писал(а):Вопрос в том как вернуть все сообщения которые шлет ОС обратно в оконную процедуру, чтоб можно было нормально их обрабатывать?
Установить свой обработчик оконных сообщений через SetWindowLong или использовать хуки. По другому насколько я знаю никак.
Re: Как заставить Lazarus выдавать все сообщения в WinProc?
Alexx2000 писал(а):Установить свой обработчик оконных сообщений через SetWindowLong или использовать хуки. По другому насколько я знаю никак.
При этом способе обработчик то перехватывается, а сообщения всеравно не идут
Re: Как заставить Lazarus выдавать все сообщения в WinProc?
.wOvAN писал(а):... но дело в том что под целевую ось это резко ограничивает возможности разработки, а то и вообще делает невозможным реализовать, те или иные специфичные вещи.
если всё столь "специфично", что мешает описать свой контрол со своим виджетом?
тогда на уровне win32 всё будет во власти этого виджета (как сделано для RichMemo).
кстати, какие "те или иные специфичные вещи" требуется реализовать?
и как так получается, что при перехваченном обработчике (через SetWindowLong WNDPROC) сообщения не идут?! а что тогда идёт?
Re: Как заставить Lazarus выдавать все сообщения в WinProc?
Самая простой пример добавление кнопки в заголовок окна, написание формы на уровне api как то не вариант.
Вообще мне такая политика ограничения не понятна, вроде бы если разрабы лазаруса не хотят обрабатывать не кроссплатформенные сообщения их право, зачем же создавать трудности остальным?
Добавлено спустя 1 час 3 минуты 26 секунд:
Как говорится стоит поругать разрабов и все начинает работать
, решил перепроверить метод с GetWindowLong/SetWindowLong и к удивлению он заработал. Хотя раньше не хотел
Всем откликнувшимся спасибо
На всякий случай прикладываю код.
Вообще мне такая политика ограничения не понятна, вроде бы если разрабы лазаруса не хотят обрабатывать не кроссплатформенные сообщения их право, зачем же создавать трудности остальным?
Добавлено спустя 1 час 3 минуты 26 секунд:
Как говорится стоит поругать разрабов и все начинает работать
Всем откликнувшимся спасибо
На всякий случай прикладываю код.
Код: Выделить всё
unit Unit1;
{$mode delphi}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
LMessages, Messages, Windows ;
type
{ TForm1 }
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FWndInstance: TFarProc;
FPrevWndProc: TFarProc;
{ private declarations }
procedure NewWndProc(var message: TMessage);
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
FWndInstance := MakeObjectInstance(NewWndProc);
FPrevWndProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
SetWindowLong(Handle, GWL_WNDPROC, LongInt(FWndInstance));
end;
procedure TForm1.NewWndProc(var message: TMessage);
begin
case message.msg of
LM_NCHITTEST : {Чего нибудь делаем} ;
end;
with message do Result := CallWindowProc(FPrevWndProc, Handle, Msg, wParam, lParam);
end;
end.
Re: Как заставить Lazarus выдавать все сообщ. в WndProc?
.wOvAN
В случае не работы GetWindowLong/SetWindowLong, нужно совершенно других разработчиков ругать
В случае не работы GetWindowLong/SetWindowLong, нужно совершенно других разработчиков ругать
Re: Как заставить Lazarus выдавать все сообщения в WinProc?
.wOvAN писал(а):На всякий случай прикладываю код.Код: Выделить всё
unit Unit1;
{$mode delphi}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
LMessages, Messages, Windows ;
type
{ TForm1 }
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FWndInstance: TFarProc;
FPrevWndProc: TFarProc;
{ private declarations }
procedure NewWndProc(var message: TMessage);
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
FWndInstance := MakeObjectInstance(NewWndProc);
FPrevWndProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
SetWindowLong(Handle, GWL_WNDPROC, LongInt(FWndInstance));
end;
procedure TForm1.NewWndProc(var message: TMessage);
begin
case message.msg of
LM_NCHITTEST : {Чего нибудь делаем} ;
end;
with message do Result := CallWindowProc(FPrevWndProc, Handle, Msg, wParam, lParam);
end;
end.
ЭТО должно работать?
