Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Не получается отправить сообщение контролу


Автор: youriy86 22.12.2011, 17:57
Здравствуйте.
У меня на форме лежит 2 компонента ListBox: TListBox и Edit: TEdit.
Свойство ListBox.AutoComplete = true стоит по умолчанию. Когда я нажимаю клавишу с какой-либо буквой, находясь при этом на ListBox'е, он автоматически перескакивает на нужную мне запись, начинающуюся с этой буквы.
Я хочу в Edit вводить текст, а в ListBox'e в этот момент должно происходить поиск записи, начинающейся с этой буквы, и установка ее в качестве выбранной.

Пробовал так (чтобы имитировать событие KeyPress на ListBox'е):

Код

procedure TFrm.EditKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  ListBox.Perform(WM_KEYDOWN, Key, 0);
end;

procedure TFrm.EditKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  ListBox.Perform(WM_KEYUP, Key, 0);
end;


Пробовал так:
Код

procedure TFrm.EditKeyPress(Sender: TObject; var Key: Char);
begin
  ListBox.Perform(WM_KEYDOWN, Ord(Key), 0);
  ListBox.Perform(WM_KEYUP, Ord(Key), 0);
end;


Пробовал через SendMessage, но я так понял это то же самое. Ничего не получается.

Вопрос: как имитировать возникновение события, которое уже заложено в коде (поиск по введенной с клавиатуры буквы) в ListBox'е с помощью Edit (ну или другого контрола, поддерживающего функцию ввода текста)? Помогите плиз.

Автор: superVad 22.12.2011, 21:30
Может что то такое подойдет:
Код

procedure TForm1.Edit1Change(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to ListBox1.Items.Count - 1 do
    if Pos(AnsiUpperCase(TEdit(Sender).Text), AnsiUpperCase(ListBox1.Items[i])) = 1 then
    begin
      ListBox1.ItemIndex := i;
      Break;
    end;
end;

Автор: youriy86 23.12.2011, 06:59
Это то понятно, что то что мне надо, можно сделать каким-нибудь похожим способом. Но вопрос то в другом, как имитировать наступление этого события у контрола

Автор: youriy86 26.12.2011, 06:53
ап

Автор: k0rvin 26.12.2011, 08:00
Код

procedure TFrm.EditKeyPress(Sender: TObject; var Key: Char);
begin
  ListBox.KeyPress(ListBox, Key);
end;

?

Автор: MetalFan 26.12.2011, 09:23
Цитата(youriy86 @  22.12.2011,  17:57 Найти цитируемый пост)
Пробовал так:

Ну во-первых кто будет lParam заполнять?
во-вторых... если нужно сделать "редирект" сообщений, то почему бы не перекрыть оконную процедуру исходного винконтрола?

Автор: youriy86 26.12.2011, 09:37
Цитата(MetalFan @  26.12.2011,  09:23 Найти цитируемый пост)
Ну во-первых кто будет lParam заполнять?

Я думал там достаточно 0 оставить. Что следует поставить? Я пробовал вставить SizeOf(Key) - не помогло.

Цитата(MetalFan @  26.12.2011,  09:23 Найти цитируемый пост)
во-вторых... если нужно сделать "редирект" сообщений, то почему бы не перекрыть оконную процедуру исходного винконтрола? 

Перекрыть оконную процедуру - это как? В смысле назначить ему событие OnKeyPress?

Автор: CROTishka 11.1.2012, 15:13
то что вы просите, делается в 2строчки:
Код

type

  TEdit = class(StdCtrls.TEdit)
    procedure Dispatch(var Message); override;
  end;

  TForm1 = class(TForm)
    edt1: TEdit;
    mmo1: TMemo;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TEdit }

procedure TEdit.Dispatch(var Message);
begin
  if (TMessage(Message).Msg = WM_CHAR) and (TForm1(Self.Owner).mmo1 <> nil)
  then
    TForm1(Self.Owner).mmo1.Dispatch(Message);
  inherited;
end;



Но сдаётся мне, вы не тем заняты. 
сага о x y и z :
http://www.google.ru/url?sa=t&rct=j&q=%D1%81%D0%B0%D0%B3%D0%B0%20%D0%BE%20x%20y%20%D0%B8%20z&source=web&cd=1&ved=0CB0QFjAA&url=http%3A%2F%2Fwww.gunsmoker.ru%2F2008%2F10%2Fx-y-z.html&ei=zXwNT7e2GYap4gSf5szvBQ&usg=AFQjCNEfQal1tBzmpfL7lsfV_FQDCrhJRw

Автор: youriy86 18.1.2012, 07:58
Спасибо, работает, но мне хотелось бы еще текст в едите видеть.

Ну а насчет саги, я почитал, интересно smile но по-моему в данном случае это как раз таки X. Потому что ко мне приходит пользователь и говорит:"Меня не устраивает нажимать на ЛистБоксе, хочу в отдельном эдите и чтобы там искалось".

Автор: CROTishka 18.1.2012, 10:08
Цитата

Спасибо, работает, но мне хотелось бы еще текст в едите видеть.

А для чего там по-вашему строчка с inherited!?!?
Значит вы что-то не так скопировали.
Цитата

Потому что ко мне приходит пользователь и говорит:"Меня не устраивает нажимать на ЛистБоксе, хочу в отдельном эдите и чтобы там искалось". 

Как связана эта задача(постановка), и то, что вы просите?
Держите:
Код

type

  TEdit = class(StdCtrls.TEdit)
  private
    FLastTime: Cardinal;
  protected
    procedure KeyPress(var Key: Char); override;
  end;

  TForm1 = class(TForm)
    lst1: TListBox;
    edt1: TEdit;
    procedure edt1KeyPress(Sender: TObject; var Key: Char);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.edt1KeyPress(Sender: TObject; var Key: Char);
var
  x: TWMKey;
begin
  x.Msg := WM_CHAR;
  x.CharCode := Ord(Key);
  lst1.Dispatch(x);
end;

procedure TEdit.KeyPress(var Key: Char);
begin
  inherited;
  if GetTickCount - FLastTime >= 500 then
    Text := '';
  FLastTime := GetTickCount;
end;

Автор: youriy86 23.1.2012, 07:15
Спасибо большое, все работает.

Добавлено @ 07:22
Код

procedure TForm1.Edit1Change(Sender: TObject);
begin
  with ListBox1 do
    ItemIndex := Perform(LB_SELECTSTRING, ItemIndex, LongInt(Edit1.text));
end;


А что Вы думаете, насчет такого? У меня вроде работает.
И я не понимаю для чего стоит обнуление текста у TEdit на KeyPress.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)