スポンサーリンク

wxListBoxに表示可能な最大要素数を計算

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:
};

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: