TL;DR
C++ MFC CListView では、CListView にキーボード フォーカスがあるときにユーザーが入力した文字に基づいて自動選択を防ぐ方法は?
状況:
CListView を使用して英数字文字列を含む行のコレクションを表示する MFC アプリケーション。リストを選択してキーボード フォーカスを設定し、文字を入力すると、リストの選択は、最初の列の値がその文字で始まる最初の項目にジャンプします。
つまり、たとえば「r」と入力すると、リスト リストの選択は文字「r」で始まる最初の項目にジャンプします。次に、たとえば「b」と入力すると、リストの選択は文字 b で始まる最初の項目にジャンプします。等々。
VS2019 New Project ウィザードを使用して新しいアプリケーションを作成すると、この動作は CListView で自動的に行われます。
質問1:
上下矢印キーのナビゲーションを妨げずに、この自動選択が起こらないようにするにはどうすればよいですか?
これに頭を悩ませている過程で、クラス WC_LISTVIEW を持つまっすぐな WIN32 ウィンドウもこのように動作することがわかったので、これをオンまたはオフにするスタイルが必要だと思いますか?
スタイルの場合は、OnInitialUpdate() の ModifyStyle() 呼び出しで変更できます。または、HWND を使用してコントロールにメッセージを送信することもできますか?
では... 質問 2:
CListView のメッセージ処理ループで雑草に巻き込まれることなく、これをオフにすることはできますか?
コメント
CListView が実行できる高度な複数文字部分文字列一致検索を探しているわけではありません。
文字または数字を入力したときに CListView が選択を変更するのを停止し、上/下矢印、ページアップ/ページダウン、およびホーム/エンドキーに応答して選択を変更する通常の動作を継続する必要があります。 . そのため、必要に応じて検索をオフにしてください。
コード
もっとコードを投稿することもできますが、それは VS2019 New Project -> C++ -> MFC -> Explorer Style ウィザードの出力になります。
私が行った唯一の関連する変更は、CListView 派生クラスの名前を MyCFileListView に変更し、リストを作成することでした。
リストに入力します。
static void AddData(CListCtrl &ctrl, int row, int col, const wchar_t *str) {
LVITEM lv;
lv.iItem = row;
lv.iSubItem = col;
lv.pszText = (LPTSTR) str;
lv.mask = LVIF_TEXT;
if(col == 0)
ctrl.InsertItem(&lv);
else
ctrl.SetItem(&lv);
}
void MyCFileListView::OnInitialUpdate() {
CListView::OnInitialUpdate();
ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
CListCtrl &the_list = GetListCtrl();
the_list.InsertColumn(0, L"File");
the_list.SetColumnWidth(0, 80);
the_list.InsertColumn(1, L"Size");
the_list.SetColumnWidth(1, 80);
the_list.InsertColumn(2, L"Modified");
the_list.SetColumnWidth(2, 80);
the_list.InsertColumn(3, L"Type");
the_list.SetColumnWidth(3, 80);
the_list.InsertColumn(4, L"Description");
the_list.SetColumnWidth(4, 80);
UINT ii = 0;
for (const FileInfo &fi: program_state.file_list) {
AddData(the_list, ii, 0, fi.filename.c_str());
AddData(the_list, ii, 1, fi.filesize.c_str());
AddData(the_list, ii, 2, L"NYI");
AddData(the_list, ii, 3, fi.filetype.c_str());
AddData(the_list, ii, 4, L"");
ii++;
}
}
FileInfo は単なるコンテナーです (構造体である必要があります):
class FileInfo {
public:
FileInfo() : n_filesize(0), epoch_ms(0), is_dir(false) {};
virtual ~FileInfo() {
}
std::wstring filename;
std::wstring ext;
std::wstring fqfilename;
std::wstring filesize;
size_t n_filesize;
__int64 epoch_ms;
std::wstring mod_date;
std::wstring filetype;
std::wstring description;
std::wstring properties;
bool is_dir;
};
そして program_state.file_list は次のように宣言されています。
class ProgramState {
public:
// ...
std::vector<FileInfo> file_list;
// ...
};
私はCListViews、WIN32 ListViews AKA WC_LISTVIEW、それらのスタイルと拡張スタイルに関するMSのページを調べましたが、この動作について何も見つかりません:
https://docs.microsoft.com/en-us/cpp/mfc/reference/clistview-class?view=msvc-160
https://docs.microsoft.com/en-us/windows/win32/controls/list-view-controls-overview
https://docs.microsoft.com/en-us/windows/win32/controls/extended-list-view-styles
https://docs.microsoft.com/en-us/windows/win32/msi/listview-control
…その他、数え切れないほどあります。
この動作が非常に優れているため、誰も無効にしたくないかのようです:-)