Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Компоненты и классы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.11.2011, 14:41
user686 user686 вне форума
Прохожий
 
Регистрация: 02.11.2011
Сообщения: 8
Репутация: 10
По умолчанию TListBox с функцией фильтрующего поиска

На базе TListBox реализовал фильтрующий поиск. Когда вводишь символ, поверх листбокса появляются TEdit и еще один листобокс. Текст вводится в TEdit, отфильтрованные результаты поиска - в дочерний листбокс:



Проблема: при кликаньи дочернего листбокса проявляется (моргает) основной листбокс, также иногда проявляются вертикальный скролбар родительского.
Причем, этот скролбар при входе в режим поиска я убираю функцией ShowScrollBar(Handle,SB_VERT,false), но при кликаньи он все равно появляется.

Собственно, вопрос: как заставить родительский листбокс не отрисовывать себя, чтобы никаких морганий не было и скролбары не появлялись?
Ответить с цитированием
  #2  
Старый 02.11.2011, 15:00
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

LockWindowUpdate(...).
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 02.11.2011, 15:19
user686 user686 вне форума
Прохожий
 
Регистрация: 02.11.2011
Сообщения: 8
Репутация: 10
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
LockWindowUpdate(...).

Нет. В этом случае вообще все внутри листбокса перестает отрисовываться.

Необходимо сделать так, чтобы только строки и скролбары родительского листобокса не отрисовывались. Дочерние контролы должны отрисовываться как обычно.
Ответить с цитированием
  #4  
Старый 02.11.2011, 15:36
Pyro Pyro вне форума
Так проходящий
 
Регистрация: 18.07.2011
Сообщения: 805
Версия Delphi: 7Lite
Репутация: 6063
По умолчанию

а если так?
PHP код:
SendMessage(HandleWM_SETREDRAWWPARAM(False), 0);
    
SendMessage(HandleWM_SETREDRAWWPARAM(True), 0); 
Ответить с цитированием
  #5  
Старый 02.11.2011, 16:05
user686 user686 вне форума
Прохожий
 
Регистрация: 02.11.2011
Сообщения: 8
Репутация: 10
По умолчанию

Цитата:
Сообщение от Pyro
а если так?
PHP код:
SendMessage(HandleWM_SETREDRAWWPARAM(False), 0);
    
SendMessage(HandleWM_SETREDRAWWPARAM(True), 0); 

Вот это помогло. Строки родительского листбокса не проявляются.

Теперь осталась проблема со скролбарами.
Ответить с цитированием
  #6  
Старый 02.11.2011, 17:00
user686 user686 вне форума
Прохожий
 
Регистрация: 02.11.2011
Сообщения: 8
Репутация: 10
По умолчанию

По поводу скролбаров:

Удалось только перманентно отключить скроллбары через CreateParams, исключить из стиля флаги WS_HSCROLL и WS_VSCROLL. Но это не решает проблему, так как скролбары нужны, когда поиск не используется.

Их нужно именно включать и отключать. В принципе, для этого есть SetWindowLong, но вертикальный скролбар почему-то не отключается. Код следующий:

Код:
    style:=GetWindowLong(Handle,GWL_STYLE);
    SetWindowLong(Handle,GWL_STYLE,style and not WS_HSCROLL and not WS_VSCROLL);
    SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_FRAMECHANGED);

Вертикальный скролбар не убирается. Здесь обсуждалась моя проблема, но там пришли к выводу, что это вообще невозможно - отключать скроллбары у уже созданных листбоксов. Я что-то сомневаюсь в этом, может просто что-то еще надо сделать?
Ответить с цитированием
  #7  
Старый 02.11.2011, 17:21
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Может вы не тем путем пошли? Может проще было завести дополнительно TStringList куда поместить исходные данные. А вот при поиске отображать в вашем листбоксе только отфильтрованные данные.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #8  
Старый 02.11.2011, 17:36
user686 user686 вне форума
Прохожий
 
Регистрация: 02.11.2011
Сообщения: 8
Репутация: 10
Лампочка Решение найдено

Цитата:
Сообщение от Страдалецъ
Может вы не тем путем пошли? Может проще было завести дополнительно TStringList куда поместить исходные данные. А вот при поиске отображать в вашем листбоксе только отфильтрованные данные.

В этом случае геморроя еще больше. Та же проблема со скроллбарами + ручная отрисовка.

Проблема со скролбарами решилась при помощи CreateParams + RecreateWnd. В CreateParams, в зависимости от режима, исключаются/не исключаются флаги WS_HSCROLL и WS_VSCROLL, а при активации и деактивации поиска вызывается RecreateWnd. Видимо, это единственное решение.

Спасибо всем за советы.
Ответить с цитированием
  #9  
Старый 02.11.2011, 20:52
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Не думаю, что гемороя больше будет. Вот вполне рабочий вариант:
Код:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure ListBox1KeyPress(Sender: TObject; var Key: Char);
    procedure Edit1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    SrcData: TStringList;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ListBox1KeyPress(Sender: TObject; var Key: Char);
begin
 Edit1.Perform(WM_CHAR, LongInt(Key), 0);
end;

procedure TForm1.Edit1Change(Sender: TObject);
Var Index: Integer;
begin
 ListBox1.Clear;
 SrcData.Find(Edit1.Text, Index);
 while Index <= SrcData.Count - 1
 do begin
    if AnsiUpperCase(Copy(SrcData.Strings[Index],1,Length(Edit1.Text))) <> AnsiUpperCase(Edit1.Text)
    then Break;
    ListBox1.Items.Add(SrcData.Strings[Index]);
    Inc(Index);
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 SrcData := TStringList.Create;
 SrcData.CaseSensitive := False;
 SrcData.Text := ListBox1.Items.Text;
 SrcData.Sort;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 SrcData.Free;
end;

end.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #10  
Старый 02.11.2011, 22:14
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

А что мешало на момент фильтрации сделать невидимым (Visible:=False) родительский ListBox?
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #11  
Старый 03.11.2011, 01:15
user686 user686 вне форума
Прохожий
 
Регистрация: 02.11.2011
Сообщения: 8
Репутация: 10
По умолчанию

Цитата:
Сообщение от angvelem
А что мешало на момент фильтрации сделать невидимым (Visible:=False) родительский ListBox?
Мешало то, что весь компонент скрывался.
Ответить с цитированием
  #12  
Старый 03.11.2011, 01:31
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Ну сам же писал:
Цитата:
...поверх листбокса появляются TEdit и еще один листобокс...
выражай тогда свои мысли яснее.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #13  
Старый 03.11.2011, 11:28
user686 user686 вне форума
Прохожий
 
Регистрация: 02.11.2011
Сообщения: 8
Репутация: 10
По умолчанию

Цитата:
Сообщение от angvelem
Ну сам же писал:

выражай тогда свои мысли яснее.
Что тебе непонятно?
Ответить с цитированием
  #14  
Старый 03.11.2011, 13:19
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

еще один рабочий вариант (2 TListBox, 1 TEdit - все как у ТС):

Код:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Edit1: TEdit;
    ListBox2: TListBox;
    procedure ListBox1KeyPress(Sender: TObject; var Key: Char);
    procedure Edit1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Edit1Change(Sender: TObject);
    procedure ListBox2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses StrUtils;

{$R *.dfm}

procedure TForm1.ListBox1KeyPress(Sender: TObject; var Key: Char);
begin
  Edit1.Text:=Key;
  Edit1.Visible:=True;
  ListBox2.Visible:=True;
  Edit1.SetFocus;
  Edit1.SelStart:=-1;
end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key=VK_ESCAPE then
  begin
    Edit1.Hide;
    ListBox2.Hide;
    ListBox1.SetFocus;
  end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
var
  i: Integer;
begin
  ListBox2.Clear;
  for i:=0 to ListBox1.Items.Count-1 do
  begin
    if AnsiStartsText(Edit1.Text, ListBox1.Items[i]) then
      ListBox2.Items.Add(ListBox1.Items[i]);
  end;
end;

procedure TForm1.ListBox2Click(Sender: TObject);
var
  i: Integer;
  Key: Word;
begin
  i:=ListBox1.Items.IndexOf(ListBox2.Items[ListBox2.ItemIndex]);
  if i<>-1 then
  begin
    ListBox1.ItemIndex:=i;
    Key:=VK_ESCAPE;
    Edit1KeyUp(Edit1, Key, []);
  end;
end;

end.

http://data.cod.ru/130546
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:18.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter