Combo-box items list floating on the form when mouse scrolling

Viewed 336

The issue is related to regular TComboBox component. The problem exists when accessing drop list from the combo-box and next when scrolling through the form, fields list remains in the same place. It's really annoying from the user perspective.

enter image description here

Is there any way to automatically lose the control focus when scrolling through the form? Any other ideas?

Please see sample code below to recreate the issue.

unit Unit10;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, vcl.wwcheckbox, Vcl.Mask, vcl.wwdbedit, Vcl.ExtCtrls,
  vcl.wwdotdot, vcl.wwdbcomb, vcl.wwdbdatetimepicker;

type
  TForm10 = class(TForm)
    grpPanels: TCategoryPanelGroup;
    pnl1: TCategoryPanel;
    pnl2: TCategoryPanel;
    ComboBox1: TComboBox;
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
      var Handled: Boolean);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  var
  Form10 : TForm10;

implementation

{$R *.dfm}

procedure TForm10.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
  var Handled: Boolean);
begin
   if WheelDelta > 0 then
      grpPanels.Perform(WM_VSCROLL, SB_LINEUP, 0)
   else
      grpPanels.Perform(WM_VSCROLL, SB_LINEDOWN, 0);
end;

procedure TForm10.FormShow(Sender: TObject);
var
   i: Integer;
begin
   for i := 0 to 5 do
      ComboBox1.Items.Add(IntToStr(i));
end;

end. 
2 Answers

Is there any way to automatically lose the control focus when scrolling through the form? Any other ideas?

Add to the beginning of FormMouseWheel() either of the following:

Assure the combo loses focus:

  if ActiveControl is TComboBox then
    FocusControl(nil);

Alternative, assure the dropdown is closed, but retain focus

  if ActiveControl is TComboBox then
    TComboBox(ActiveControl).DroppedDown := False;

I've found another way to handle this issue and want to share it with you. The thing is the problem also exists for other WIN32 vcl components like TDateTimePicker, TComboBox etc.

To handle all this cases with not losing control focus we can call CM_CANCELMODE message at the beginning of FormMouseWheel() :

for i := 0 to ComponentCount - 1 do
   if Components[i] is TWinControl then
      TWinControl(Components[i]).Perform(CM_CANCELMODE, 0, 0);
Related