Как отключить прокрутку контрольного списка при нажатии на последний элемент?

#delphi #vcl #delphi-xe7 #delphi-10.2-tokyo #checklistbox

#delphi #vcl #delphi-xe7 #delphi-10.2-Токио #контрольный список

Вопрос:

Если в контрольном списке достаточно элементов, поэтому у него есть полоса прокрутки, всякий раз, когда нажимается последний элемент, он прокручивается до следующего, что приводит к нежелательному поведению:

  • проверка / снятие флажка со следующего элемента вместо того, на который я нажал

Протестировал его как в Delphi XE7, так и в более новой версии, 10.2 Tokyo, и он делает то же самое

Попытался захватить сообщение WM_LBUTTONDOWN и отследить его, что привело к нахождению точного места, где все происходит.

Vcl.Controls.pas

 ...
procedure TControl.WMLButtonDown(var Message: TWMLButtonDown);
begin
  SendCancelMode(Self);

  inherited; //there it scrolls by 1 line

  if csCaptureMouse in ControlStyle then
    MouseCapture := True;
  if csClickEvents in ControlStyle then
    Include(FControlState, csClicked);

  DoMouseDown(Message, mbLeft, []); // it does the check/uncheck
end;
...
  

Код для воспроизведения: (и поместите флажок в форму)

 ...

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  CheckListBox1.Height := 145; //just so it's short enough
  for i := 0 to 30 do
  begin
CheckListBox1.Items.Add('Item' IntToStr(i));
  end;
end;
...
  

Затем щелкните поле элемента, которое отображается внизу

Также пытался пройти через блок, который содержит все о контрольном списке (Vcl.CheckLst, но не нашел ничего полезного

Редактировать

Бракнику обнаружил, что он может воспроизвести его только с частичными элементами, что, похоже, относится и ко мне

Его решение: установите для свойства IntegralHeight значение True, чтобы предотвратить эту проблему.

Комментарии:

1. «вы можете пропустить вещи, связанные с windowproc» — Пожалуйста, пропустите это уже — удалите эту часть из кода в вопросе, опубликуйте пример воспроизведения, который не включает странную попытку исправления.

2. В этом случае он ничего не делает, кроме как позволяет вам вводить его через точку останова, но я удалю его.

3. ProcessMessages при обработке входного сообщения может привести к обработке другого ввода до фактического ввода.

4. Это было проницательно, спасибо за информацию, буду уделять больше внимания «дополнительным битам», когда буду задавать вопросы в будущем.

5. Возможный обходной путь — установить IntegralHeight значение true или отрегулировать высоту, чтобы не было частичных элементов. Я мог воспроизвести проблемное поведение только с частичным элементом.