Search code examples
delphivclvirtualtreeviewtvirtualstringtree

How do I make a TVirtualStringTree process key presses with a higher precedence?


We've got a certain search form at work that was revamped recently. Its functionality is that of a standard search form: enter a few criteria in some boxes at the top, hit the Search button, and display results in a grid down below. But it was ugly and very limited in functionality, so one of my coworkers rebuilt it... right before leaving for a new job. Now I'm trying to complete the last few details.

One of the changes was replacing the old TListBox grid with a much more powerful TVirtualStringTree. But in the process, it appears to have broken something: before, if you clicked on a row in the grid (giving the grid in put focus) and hit Enter, the appropriate event handler would fire and deal with your input, opening the detail view for the selected item. In this grid, however, pressing Enter causes the TButton on the form with the Default = true property to fire its OnClick instead.

How can I make the TVirtualStringTree take precedence when it has input focus, so that it will respond to the user pressing Enter itself before (and preferably instead of) dispatching it to the form?


Solution

  • Handle the WM_GETDLGCODE message and include DLGC_WANTALLKEYS in the returned value. For example:

    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
    
    ....
    
    procedure TMyControl.WMGetDlgCode(var Message: TWMGetDlgCode);
    begin
      inherited;
      Message.Result := DLGC_WANTALLKEYS;
    end;
    

    Depending on whether or not your control already handles this message and returns something other than 0 you might need to use:

    Message.Result := Message.Result or DLGC_WANTALLKEYS;
    

    If you don't want to modify the code for this class then use an interposer or set the WindowProc property of the control to intercept its window procedure.