Oprogramowanie zdarzenia OnKeyDown w ListBox

0

Witam wszystkich, mam pytanie odnośnie komponentu ListBox, mianowicie chciałbym samemu oprogramować zdarzenie OnKeyDown pod kątem liter A .. Z i samemu zareagować na podany w parametrze kod klawisza; Niestety jeżeli nawet wcisnę odpowiedni klawisz (jakąś literę) to mój kod się wykonuje, ale kod klawisza zostaje dalej mimo, że przypisuję do niego kod zerowy. Poniżej przykładowy kod:

procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  { [...] }

  if Key in [$41 .. $5A] then
    begin
      { moje operacje }
    end;

  { [...] }

  Key := $0;
end;

Mimo tego kod klawisza nie zostaje wyzerowany i przechodzi dalej, gdzie zostaje obsłużony standardowym działaniem - czyli zaznacza item, którego pierwszą literą jest podany klawisz w argumencie procedury.

Moje pytanie brzmi: w jaki sposób wyzerować kod klawisza tak, by komponent nie zaznaczał "po swojemu" itema i tym samym całkowicie przejąć kontrolę nad naciskanymi klawiszami (literami)?

0

Key się zeruje poprawnie, tylko akcja zmiany elementu ListBox-a jest wykonywana przed Twoim zerowaniem. Zrób to w OnKeyPress.

0

Czyli sugerujesz, że najpierw mam wyzerować klawisz w później wykonać zaznaczenie jakiegoś mojego itema? Sprawdzę. W OnKeyPress raczej tego nie zrobię, bo dochodzą do sprawdzania klawisze takie jak: VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_SPACE, VK_PRIOR, VK_NEXT, VK_HOME i VK_END, a ich nie obsłużę w OnKeyPress.

Nawet gdybym zrobił to w OnKeyPress to i tak w OnKeyDown najpierw zostałby obsłużony klawisz (czyli komponent wcześniej by już zareagował na klawisz) a dopiero później wykonałby się mój kod.

Kombinowałem już z tymi metodami i zrobiłem to w OnKeyPress. Działało ale nie do końca, bo było widać ingerencję komponentu w działanie; Czasem (nie określę dokładnie) komponent reagował na klawisz, częściej jednak wykonywał się mój kod.

Napiszę jeszcze czy przestawienie zerowania klawisza przez operacje zaznaczające dało jakiś rezultat. Dziękuję za sugestię.

0
procedure TForm1.ListBox1KeyPress(Sender: TObject; var Key: char);
var
  i:integer;
  c:char;
begin
  if key in ['a'..'z','A'..'Z'] then
     begin
       c:=upcase(key);
       for i:=0 to listbox1.items.count-1 do
           begin
             if c=upcase(listbox1.items[i][1]) then
                begin
                  listbox1.ItemIndex:=i;
                  key:=#0;
                  break;
                end;
           end;
     end;
end; 

Proste że aż wstyd że ci daje gotowe.

0

Czy ja prosiłem Cię o gotowca? Czy kogokolwiek prosiłem o jakikolwiek kod? Choćby linijkę? Nie. Wstyd, że nie czytasz dokładnie :P

Nie chodziło mi o kod bo jest banalny, tylko i sugestie. Wiem, że trzeba to w ten sposób zrobić, ale to i tak nie wystarczy. Z resztą Twój kod zeruje znak jedynie wtedy, gdy znajdzie item na podaną literę, a mój zeruje znak zawsze i o to chodzi. Ja mam mieć całkowitą kontrolę nad naciskanymi klawiszami, komponent ma nic sam nie robić.

Tak jak napisałem wcześniej zdarzenie OnKeyPress nie wchodzi w rachubę, bo jest wywoływane i wykonywane po zdarzeniu OnKeyDown, czyli najpierw komponent analizuje klawisz i coś dalej z nim robi a później wywoływany jest mój kod. Czyli najpierw komponent ustawi jakiś item, a później ja ustawiam swoim algorytmem swój item i to się właśnie gryzie ze sobą.

Muszę przetestować wcześniejsze zerowanie znaku przed moim algorytmem wyszukującym i zaznaczającym wybrany item.

0

Czy ja prosiłem Cię o gotowca? Czy kogokolwiek prosiłem o jakikolwiek kod? Choćby linijkę? Nie. Wstyd, że nie czytasz dokładnie

Myślałem że skoro masz z tym problem to musi być z tym jakiś problem więc napisałem.

Nie chodziło mi o kod bo jest banalny, tylko i sugestie. Wiem, że trzeba to w ten sposób zrobić, ale to i tak nie wystarczy. Z resztą Twój kod zeruje znak jedynie wtedy, gdy znajdzie item na podaną literę, a mój zeruje znak zawsze i o to chodzi. Ja mam mieć całkowitą kontrolę nad naciskanymi klawiszami, komponent ma nic sam nie robić.

No rzeczywiście mi różnica. Tylko sprawa polega na tym że on działa.

Tak jak napisałem wcześniej zdarzenie OnKeyPress nie wchodzi w rachubę, bo jest wywoływane i wykonywane po zdarzeniu OnKeyDown, czyli najpierw komponent analizuje klawisz i coś dalej z nim robi a później wywoływany jest mój kod. Czyli najpierw komponent ustawi jakiś item, a później ja ustawiam swoim algorytmem swój item i to się właśnie gryzie ze sobą.

U mnie działa bez najmniejszego problemu. =Robisz problem z niczego. Albo coś kręcisz.

Muszę przetestować wcześniejsze zerowanie znaku przed moim algorytmem wyszukującym i zaznaczającym wybrany item.

Kombinuj bardziej, racja. W końcu mój kod który działa, działa, ale jest zły, bo... działa.

ListBox1.ItemIndex := I; ListBox1.Selected[I] := True;

I może jeszcze 5 sprawdzeń czy 'cośtam'? Kod ten był testowy więc miał być prosty. poza tym, nie wydaje mi się żebym chciał żeby mi zaznaczało item jaką literę wcisnę przy multiselect... Czepiasz się o nic...

0
Oho napisał(a)

I może jeszcze 5 sprawdzeń czy 'cośtam'?

Furious Programming napisał(a)

ListBox1.ItemIndex := I; ListBox1.Selected[I] := True;

Widzisz tu gdzieś if'a? Więc o jakim sprawdzaniu mowa;

Oho napisał(a)

nie wydaje mi się żebym chciał żeby mi zaznaczało item jaką literę wcisnę przy multiselect...

Nie Tobie to ma służyć i nie było mowy o MultiSelect, więc jest na False zakładam; Bezpieczniej ustawiać ItemIndex i od razu go podświetlać;

Strasznie jakiś nerwowy jesteś; Przecież to tylko posty, nikt Ci na złość nie chce zrobić; :P

@John Pablo- postulowałbym jednak o pokazanie kodu jaki masz, bo strzelając możemy dyskutować przez miesiąc jeszcze; Jeżeli kod, który podał Ci @Oho u Ciebie nie działa tak, jak oczekiwałeś (choć u mnie działa) to coś jest nie tak; Może faktycznie jak są dwa zdarzenia oprogramowane to jedno się z drugim gryzie;

Skoro nie chcesz korzystać z OnKeyPress to zeruj klawisz zarówno w OnKeyPress i OnKeyUp, a w OnKeyDown ustaw sobie jaki tam chcesz item i na końcu wyzeruj go; Będziesz miał pewność, że żadne zdarzenie nie będzie Ci się wcinało w paradę;

EDIT:

Oho napisał(a)

[...] Myślałem że skoro masz z tym problem to musi być z tym jakiś problem więc napisałem. [...]
[...] W końcu mój kod który działa, działa, ale jest zły, bo... działa. [...]

Uwielbiam Twoje wypowiedzi... :P

0

Nie Tobie to ma służyć i nie było mowy o MultiSelect, więc jest na False zakładam; Bezpieczniej ustawiać ItemIndex i od razu go podświetlać;

Więc chodzi o podświetlenie? hmhm... A mi się wydawało że o MultiSelect.
Cóż, skoro o tym nie wiem to widać nie jest to przydatne :P .
No ale jak tam chcesz, ja i tak póki co piszę tylko ItemIndex...

Strasznie jakiś nerwowy jesteś; Przecież to tylko posty, nikt Ci na złość nie chce zrobić;

Ja z reguły jestem strasznie (tutaj wstaw cokolwiek). :P

0

Pamiętam, że od kiedy uczyłem się o OwnerDraw (jakieś 4 lata temu) to w czytanych artykułach zawsze ustawiano ItemIndex, a później Selected; Czy to słuszne? I tak i nie; Z przyzwyczajenia jednak zawsze ustawiam Selected żeby mieć pewność, że wybrany item będzie podświetlony;

Oho napisał(a)

Ja z reguły jestem strasznie (tutaj wstaw cokolwiek).

Ja nie widziałem jeszcze spokojnego programisty :P

0
John Pablo napisał(a)

Mimo tego kod klawisza nie zostaje wyzerowany i przechodzi dalej, gdzie zostaje obsłużony standardowym działaniem - czyli zaznacza item, którego pierwszą literą jest podany klawisz w argumencie procedury

Ustaw

ListBox1.AutoComplete:=False;

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0