Czy kiedykolwiek próbowałeś odpowiadać na naciśnięcie klawisza TAB poprzez handler OnKeyPress? Odkryłeś więc prawdopodobnie, że metoda ta nie skutkuje, przynajmniej dla większości kontrolek. Problem tkwi w tym, że Windows wysyła komunikat o naciśnięciu TAB jedynie do tych kontrolek, które sobie tego zażyczą. To samo tyczy się klawiszy kursora. Więc jak system operacyjny dowiaduje się która kontrolka chce otrzymywać komunikat od klawisza TAB? System operacyjny wysyła komunikat WM_GETDLGCODE do aktywnej kontrolki, żeby zapytać, które klawisze chce ona odbierać. Zwracana wartość determinuje, które naciśnięcia klawiszy zostaną wysłane do kontrolki. Zwracana wartość może być kombinacją następujących wartości: DLGC_BUTTON DLGC_DEFPUSHBUTTON DLGC_HASSETSEL DLGC_RADIOBUTTON DLGC_STATIC DLGC_UNDEFPUSHBUTTON DLGC_WANTALLKEYS DLGC_WANTARROWS DLGC_WANTCHARS DLGC_WANTMESSAGE DLGC_WANTTABŻeby otrzymywać naciśnięcie TAB, kontrolka musi zwracać DLGC_WANTTAB, klawisze kursora - DLGC_WANTARROWS, klawisze kursora i TAB - DLGC_WANTARROWS | DLGC_WANTTAB, zaś dla wszystkich klawiszy - DLGC_WANTALLKEYS. VCL zawiera wiele przykładów wykorzystania komunikatu WM_GETDLGCODE. TToolBar odpowiada na klawisze kursora, TCustomGrid na TAB i klawisze kursora, zaś TMediaPlayer i TDBNavigator na klawisze kursora. Poniżej kilka fragmentów kodu VCL przetłumaczonych na C++ dla lepszej czytelności. void __fastcall TToolBar::WMGetDlgCode(TMessage & Message) { // tylko czasem klawisze kursora if(FInMenuLoop) Message.Result = DLGC_WANTARROWS; } void __fastcall TCustomGrid::WMGetDlgCode(TMessage & Message) { // zawsze klawisze kursora Msg.Result := DLGC_WANTARROWS; ... // czasem klawisz TAB if (Options.Contains(goTabs)) Msg.Result |= DLGC_WANTTAB; // czasem komunikat WM_CHAR if (Options.Contains(goEditing)) Msg.Result |= DLGC_WANTCHARS; } void __fastcall TMediaPlayer::WMGetDlgCode(TMessage &Message) { Message.Result = DLGC_WANTARROWS; }Uwaga: Nie twórz handlera WM_GETDLGCODE dla formy. Musisz napisać ten handler na poziomie kontrolki. |