1
votes

When I tab from another control to a combo box it shows the box with a dotted line around the text, but when I set the control to be active programmatically, it doesn't show the same focus indicator.

Is there a work-around for this behaviour?

I have Delphi XE6


MCVE

unit Unit27;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm27 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;

var
  Form27: TForm27;

implementation
{$R *.dfm}

procedure TForm27.Button1Click(Sender: TObject);
begin
  ComboBox1.SetFocus;
end;

end.

object Form27: TForm27
  Left = 0
  Top = 0
  Caption = 'Form27'
  ClientHeight = 90
  ClientWidth = 246
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Edit1: TEdit
    Left = 16
    Top = 8
    Width = 121
    Height = 21
    TabOrder = 0
    Text = 'Edit1'
  end
  object Button1: TButton
    Left = 152
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 1
    OnClick = Button1Click
  end
  object ComboBox1: TComboBox
    Left = 16
    Top = 39
    Width = 145
    Height = 21
    Style = csDropDownList
    ItemIndex = 2
    TabOrder = 2
    Text = '2'
    Items.Strings = (
      '0'
      '1'
      '2'
      '3')
  end
end

enter image description here

Start the app and left-click on Button1, which calls

  ComboBox1.SetFocus;

Notice that no focus rectangle is drawn, but the combo has focus as the following shows: Hit keyboard arrow up or arrow down. The combo item changes and now the focus rectangle becomes visible. After the focus rectangle once is shown, it is also drawn on the combo after a mouse click on Button1. So to repeat the problem, restart the app.

2
"when I set the control to be active programmatically" Exactly how are you doing this? Can we see your code please?Jerry Dodge
ComboBox.SetFocus;?Johan
Focus rectangle is drawn if you use keyboard accelerators. That's how the operating system works.Sertac Akyuz
Run notepad, file open, hit tab once, document type button has focus rectangle. Close the dialog, file open again, hit file type combo with the mouse, no focus rectangle is drawn.Sertac Akyuz

2 Answers

3
votes

This is by design of the operating system, prevents clutter on the screen when a user is not using the keyboard. Here is a thorough explanation of the reasons. And here is an explanation of how the mechanism works.

You can send a WM_UPDATEUISTATE to change the state of a window (and its child windows as per the documentation).

ComboBox1.Perform(WM_UPDATEUISTATE, MakeWParam(UIS_CLEAR, UISF_HIDEFOCUS), 0);

Above will update the UI state of the combobox as if keyboard cues are required.

You don't have to send the message at focus switch time, you can send it at form creation for instance. You can also choose to send the message to the parent form, for all the controls to behave consistently, and can include UISF_HIDEACCEL in the high-word of WParam to also show accelerator characters underlined.

Note that users already can choose to display keyboard indicators at all times system-wise. In Windows 7, the setting is at "Control Panel", "Ease of Access Center", "Make the keyboard easier to use", "Make it easier to use keyboard shortcuts", "Underline keyboard shortcuts and access keys".

2
votes

To make the focus rectangle appear on a combo box, when setting the focus programmatically, you can use the following code:

ComboBox.SetFocus; 
ComboBox.Perform(WM_SYSKEYDOWN, VK_TAB, 0);