Не проходит сообщение LM_CHAR в потомке TWinControl [РЕШЕНО]

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Не проходит сообщение LM_CHAR в потомке TWinControl [РЕШЕНО]

Сообщение Browny » 08.08.2010 20:19:32

Всех приветствую!
Столкнулся с невыполнением обработчика сообщения LM_CHAR в потомке TListBox.
Код: Выделить всё
TPopupListBox = class(TListBox)
private
   FPopup: TComboPopup;
protected
   procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
   procedure WMLButtonUp(var Message: TLMLButtonUp); message LM_LBUTTONUP;
   procedure WMChar(var Message: TLMChar); message LM_CHAR;

Обработчики LM_KILLFOCUS и LM_LBUTTONUP отрабатывают нормально.
Проверил сейчас этот код в Delphi 5 - событие работает. Видимо, специфика LCL.
В чём может быть проблема?
Последний раз редактировалось Browny 18.08.2010 10:17:59, всего редактировалось 2 раз(а).
Аватара пользователя
Browny
новенький
 
Сообщения: 37
Зарегистрирован: 31.08.2007 10:42:55

Re: Не проходит сообщение LM_CHAR в потомке TListBox: причина?

Сообщение Maxizar » 08.08.2010 20:54:10

Хм.. и правда.. но можно попробывать CN_CHAR... или есть какая-то разница??

Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
  Messages,LMessages, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormShow(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
type

  { TPopupListBox }

  TPopupListBox = class(TListBox)
  private
     procedure WMLButtonUp(var Message: TLMLButtonUp); message LM_LBUTTONUP;
     procedure WMChar(var Message: TLMChar); message CN_CHAR;//LM_CHAR;
     procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
   //  FPopup: TComboPopup;
  protected

  Public
     constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
     end;
var
  Form1: TForm1;
  List:TPopupListBox;
implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormShow(Sender: TObject);
begin
  List:=TPopupListBox.Create(Self);
  List.Left:=10;
  List.Top:=20;
  List.Parent:=Form1;
  List.Visible:=True;
end;

{ TPopupListBox }

procedure TPopupListBox.WMKillFocus(var Message: TLMKillFocus);
begin
  List.Items.Add('Фокус ушел');
  inherited;
end;

procedure TPopupListBox.WMLButtonUp(var Message: TLMLButtonUp);
begin
  List.Items.Add('Отжали');
end;

procedure TPopupListBox.WMChar(var Message: TLMChar);
begin
  List.Items.Add(IntToStr(Message.CharCode));
  inherited;
end;

constructor TPopupListBox.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
end;

destructor TPopupListBox.Destroy;
begin
  inherited Destroy;
end;

end.

Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Не проходит сообщение LM_CHAR в потомке TListBox: причина?

Сообщение Browny » 09.08.2010 09:59:33

Maxizar, ага, работает. Пока в коде так использую, но вопрос всё равно остался. И сейчас озадачился поиском принципиальных отличий сообщений WM_CHAR и CN_CHAR.
Аватара пользователя
Browny
новенький
 
Сообщения: 37
Зарегистрирован: 31.08.2007 10:42:55

Re: Не проходит сообщение LM_CHAR в потомке TListBox: причина?

Сообщение Browny » 17.08.2010 17:56:13

Отвечаю сам себе, и на случай, если ещё кому пригодится..
Выдержка кода из $LAZARUS/lcl/interfaces/win32/win32callback.inc
Код: Выделить всё
function WindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam; LParam: Windows.LParam): LResult; stdcall;
....
....
begin
  Assert(False, 'Trace:WindowProc - Start');
  FillChar(LMessage, SizeOf(LMessage), 0);
  PLMsg := @LMessage;
  WinProcess := True;
  NotifyUserInput := False;
....
....
  case Msg of
....   
  WM_CHAR:
    begin
      {$ifdef WindowsUnicodeSupport}
      // у меня флаг неактивен
      {$else}
      PLMsg:=@LMChar;
      with LMChar do
      begin
        Msg := CN_CHAR; // а вот и подмена сообщения на пользовательское
        KeyData := LParam;
        CharCode := Word(WParam);
        Result := 0;
        Assert(False,Format('WM_CHAR KeyData= %d CharCode= %d ',[KeyData,CharCode]));
      end;
      WinProcess := false;
      {$endif}
    end;


Собственно, выполнил ещё проверку - подменил оконную функцию, и сделал PostMessage(мойWinControl.Handle, WM_CHAR, 0, 0).
Итог: в саму оконную функцию сообщение попадает. Тестовый проект во вложении к посту..

Если кто найдёт неточности или ошибки в моём сообщении - пожалуйста, напишите и исправьте! Мне это важно и интересно.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Browny
новенький
 
Сообщения: 37
Зарегистрирован: 31.08.2007 10:42:55

Re: Не проходит сообщение LM_CHAR в потомке TListBox: причина?

Сообщение Иван Шихалев » 17.08.2010 21:37:01

Может, стоит в исходном сообщении в заголовок добавить «[РЕШЕНО]»?
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: Не проходит сообщение LM_CHAR в потомке TWinControl [РЕШЕНО]

Сообщение Browny » 18.08.2010 10:21:10

Спасибо, добавил и немного изменил название темы в более правильную сторону :)
К слову, считаю, что закрывать тему на добавление записей не надо - вдруг, будут замечания или исправления?
Аватара пользователя
Browny
новенький
 
Сообщения: 37
Зарегистрирован: 31.08.2007 10:42:55


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 57

Рейтинг@Mail.ru