wxListBoxに一度に表示可能な最大アイテム数を求めたい。アイテムがある場合は、GetItemRect関数を使って要素の高さを取得できるので、コントロールのクライアント領域で割れば個数が得られる
int GetVisibleItemCount2(wxListBox* listBox) { // アイテムを一つ追加し、そのアイテムの高さを取得 listBox->Append("Sample Item"); wxRect rect; listBox->GetItemRect(0, rect); listBox->Clear(); // 追加したアイテムを削除 // アイテムの高さを取得 wxSize clientSize = listBox->GetClientSize(); // 表示可能なアイテム数を計算 int visibleItemCount = clientSize.GetHeight() / rect.height; return visibleItemCount; }
アイテムがない場合、dc.GetTextExtentで文字列の高さを取得し、クライアントの高さをそれで割ることで取得できる。
// リストボックスが一度に表示可能なアイテム数を取得 int GetVisibleItemCount(wxListBox * listBox) { // リストボックスのDCを使って一行の高さを取得し // リストボックスのクライアントサイズから表示可能なアイテム数を計算する // リストボックスのクライアントサイズを取得 wxSize clientSize = listBox->GetClientSize(); // wxClientDCを使用してデフォルトのアイテム高さを取得 wxClientDC dc(listBox); wxCoord textWidth, textHeight; // 指定した文字列の幅と高さを取得 dc.GetTextExtent("TEXT", &textWidth, &textHeight); // 表示可能なアイテム数を計算 int visibleItemCount = clientSize.GetHeight() / textHeight; return visibleItemCount; }
// ウィンドウ作成 class MyFrame : public wxFrame { // リストコントロール wxListBox* listBox; wxBoxSizer* mainSizer; public: void PostCreate() { int itemCount = listBox->GetCount(); int count = GetVisibleItemCount(listBox); int count2 = GetVisibleItemCount2(listBox); assert(count == count2); // listBoxにcount個のアイテムを追加 for (int i = 0; i < count; i++) { listBox->Append(wxString::Format("Item %d", i + 1)); } // メッセージボックスでcountを表示 wxMessageBox(wxString::Format("表示可能なアイテム数: %d %d", count,count2)); this->Layout(); // レイアウトの更新 } MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) { // メインSizer mainSizer = new wxBoxSizer(wxHORIZONTAL); this->SetSizer(mainSizer); // リストコントロール listBox = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, nullptr); mainSizer->Add(listBox, 1, wxEXPAND | wxALL, 5); // CallAfter : 現在処理中のイベントが終わったらPostCreateを実行 // コンストラクタはウィンドウ生成イベント扱い CallAfter(&MyFrame::PostCreate); } private: };