0

When I use TComboBox, user can select an item by clicking the control and selecting and item with mouse, or they can hover cursor over the control and use scroll wheel, or they can use keyboard when the control is selected.

How can I disable mouse wheel and keyboard events so that the user always has to click the control when they want to change the value? I want to prevent them from changing the value by accident. If this is not possible with TComboBox, is there some other combo box control that I could use?

For key press, I tried to disable the combo box on KeyDown event, but the selection still changes. TComboBox doesn't seem to have events for mouse wheel.

VLL
  • 9,634
  • 1
  • 29
  • 54
  • You probably just want to set the `Style` property to `csDropDownList`. I think you would need to override the combo class or manually handle all the events in order to achieve the desired behavior. –  Nov 22 '16 at 09:54
  • @RawN Style property is already `CsDropDownList`, but that does not seem to affect behavior of mouse and keyboard. – VLL Nov 22 '16 at 09:55

2 Answers2

3

You can subclass the ComboBox's WindowProc property to intercept and discard scroll and keyboard window messages:

private:
    TWndMethod PreviousWndProc;

__fastcall TMyForm::TMyForm(TComponent *Owner)
{
    PreviousWndProc = ComboBox1->WindowProc;
    ComboBox1->WindowProc = &ComboBoxWndProc;
}

void __fastcall TMyForm::ComboBoxWndProc(TMessage &Message)
{
    if (
        ((Message.Msg < WM_KEYFIRST) || (Message.Msg > WM_KEYLAST))
        && (Message.Msg != WM_MOUSEWHEEL)
        )
    {
        PreviousWndProc(Message);
    }
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

Changing value requires that the combo box has focus. So a possible workaround is to remove focus in CloseUp event handler, which is called after user has selected a value. However, this does not completely disable events. User can still select the control with tab key, and obtain focus that way.

To remove focus in CloseUp handler, it seems that it is not enough to set Focused property of the parent form to NULL. You must move focus to another control. TEdit seems to have fewest side effects. To hide it from the user, you must set width and height to 1, and AutoSize and TabStop to false. Enable and Visible must be true.

void __fastcall TForm1::ComboBox1CloseUp(TObject *)
{
    // Remove focus from this control to prevent changing value
    // when drop down list is closed
    if (OtherControl->CanFocus()) {
        OtherControl->SetFocus();
    }
}
VLL
  • 9,634
  • 1
  • 29
  • 54