- ベストアンサー
CLRでのListBoxのオーナードローのやり方
- Visual C++のCLRでフォームアプリケーションを作っていて、ListBoxのオーナードローの方法がわからないので質問させてもらいました。
- CLRでプログラミングしたことが無く書籍などを読んだこともなく見よう見まねで作っています。
- ListBoxのオーナードローの方法を教えてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
ある程度の法則性はあるのでC# → C++/CLIはそれほど難しい置き換えじゃないはずですが。 1.new → gcnew 2.gcnewで確保するオブジェクトを宣言するときは^を付けて参照型に 3.メンバー参照の.を->に(第1階層だけ) 4.ネームスペース参照の.を::に #他に何かあったかな…… もちろん単純に置き換えではうまく行かないケースもあるはずなのでそこはケースバイケースで。
その他の回答 (5)
- FAY
- ベストアンサー率49% (95/193)
・・・ほぼそのままだと思うんだけど private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { ListBox1->DrawMode = DrawMode::OwnerDrawFixed; //ListBox1に項目を追加する for (int i = 0; i < 10; i++) ListBox1->Items->Add(String::Format("{0}番目の項目", i)); } //DrawItemイベントハンドラ //項目を描画する private: System::Void ListBox1_DrawItem(System::Object^ sender, System::Windows::Forms::DrawItemEventArgs^ e) { { //背景を描画する //項目が選択されている時は強調表示される e->DrawBackground(); //文字を描画する色の選択 Brush^ b = nullptr; if ((e->State & DrawItemState::Selected) != DrawItemState::Selected) { //選択されていない時 switch (e->Index % 3) { case 0: b = gcnew SolidBrush(Color::Red); break; case 1: b = gcnew SolidBrush(Color::Blue); break; case 2: b = gcnew SolidBrush(Color::Green); break; } } else { //選択されている時はそのままの前景色を使う b = gcnew SolidBrush(e->ForeColor); } //描画する文字列の取得 String^ txt = safe_cast<ListBox^>(sender)->Items[e->Index]->ToString(); //文字列の描画 e->Graphics->DrawString(txt, e->Font, b, e->Bounds); //フォーカスを示す四角形を描画 e->DrawFocusRectangle(); }
お礼
回答ありがとうございます。 C#からの変換ってほとんど変えなくで済むんですね。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
下記URL参照。 VS2008:C++/CLIprojectです。
お礼
回答ありがとうございます。 わざわざ作例を作ってくれありがとうございます。 うまく作れました。
- machongola
- ベストアンサー率60% (434/720)
こんばんは。 このオーナードローは、様々なコントロールをカバーしているので、モノによっては使わないフラグもあります。 その他、選択はされているが、キーボード操作によってフォーカスが別のアイテムに逃げている、コントロール自体がディセーブルされた、特定のアイテムだけがディセーブルされたなど、色々な状況があり、これ等はモノによって違いがありますので、取り出したに確認し、順を追って描きあげて行きます。 一通り描いた後は、アイテムやコントロールをディセーブルにしたり、アイテムを選択したままタブを押して、フォーカスを逃がす等、色々と確認して下さい。 また、再描画が必要になるとアイテムが一つも存在しない時ですら、飛び込んでくるので其の点も要注意です。 C#サンプルの修正ではありませんが、以下参考程度で。 private: generic<typename T> static System::Boolean IsA(T a, T b) { return (safe_cast<int>(a) & safe_cast<int>(b)) == safe_cast<int>(b); } private: System::Void listBox1_DrawItem(System::Object^ sender, System::Windows::Forms::DrawItemEventArgs^ e) { //このキャストは確定的な筈 System::Windows::Forms::ListBox^ listBox = static_cast<System::Windows::Forms::ListBox^>(sender); //アイテムの色 System::Drawing::Color crItem = e->BackColor; //フォントの色 System::Drawing::Color crFont = e->ForeColor; //背景を描画する e->DrawBackground(); //アイテムが一つも無い時でも入り込んでくるので引き返す if(e->Index == -1) return; //項目が選択されている時は強調表示される if(this->IsA(e->State, DrawItemState::Selected)) { crItem = System::Drawing::Color::FromArgb(220, 220, 255); crFont = System::Drawing::Color::FromArgb(170, 170, 255); } //マウスが当たった時 if(this->IsA(e->State, DrawItemState::HotLight)) { crItem = System::Drawing::Color::FromArgb(248, 248, 255); } //灰化又はディセーブルされた時 if(this->IsA(e->State, DrawItemState::Disabled) || this->IsA(e->State, DrawItemState::Grayed)) { crItem = System::Drawing::Color::FromArgb(220, 220, 220); } //ブラシの作成 System::Drawing::Brush^ brItem = gcnew System::Drawing::SolidBrush(crItem); System::Drawing::Brush^ brFont = gcnew System::Drawing::SolidBrush(crFont); //アイテムに着色 e->Graphics->FillRectangle(brItem, e->Bounds); //フォントを描く e->Graphics->DrawString(listBox->Items[e->Index]->ToString(), listBox->Font, brFont, e->Bounds); //フォーカスが当たっていれば描く(アイテムの色彩を反転させるので、最後に描く) if(this->IsA(e->State, DrawItemState::Focus)) { e->DrawFocusRectangle(); } //ブラシの消去 delete brItem; delete brFont; }
お礼
回答ありがとうございます。 うまく自分のやりたいことができました。 オーナードローするときはいろいろ考えたほうが良いのですね。 とても勉強になりました。
- D-Matsu
- ベストアンサー率45% (1080/2394)
ちょっと変なので修正。 ここは、後ろのswitch内でオブジェクトを生成する部分が1に該当するため、遡って2のケースが適用されます。 null→NULLとするのは#2で書いた通り。
お礼
ありがとうございます。 うまくできました。 他もC#からの変換できそうです。
- D-Matsu
- ベストアンサー率45% (1080/2394)
> Brush b = null; > でコンパイルエラーになります。 これは後に続くswitch()の中と合わせて1と2の複合です。 なお、nullはNULLとしてください。
補足
回答ありがとうございます。 参考にさせてもらいます。 とりあえず Brush b = null; でコンパイルエラーになります。 C3622: 'System::Drawing::Brush': 'abstract' として宣言されたクラスをインスタンス生成することはできません C2065: 'null' : 定義されていない識別子です。 どういうことでしょうか