Visual C++のCLRでフォームアプリケーションを作っていて、ListBoxのオーナードローの方法がわからないので質問させてもらいました。
CLRでプログラミングしたことが無く書籍などを読んだこともなく見よう見まねで作っています。
やりたいことはとりあえず
http://dobon.net/vb/dotnet/control/lbownerdraw.h …
にあることです。
サンプルプログラムはVBとC#でC++がありません。
MSDN(http://msdn.microsoft.com/ja-jp/library/system.w …)も同様でVBとC#のサンプルプログラムでC++がありませんでした。
とりあえず。
C#のサンプル-----------------------------------------------
//DrawItemイベントハンドラ
//項目を描画する
private void ListBox1_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e)
{
//背景を描画する
//項目が選択されている時は強調表示される
e.DrawBackground();
//文字を描画する色の選択
Brush b = null;
if ((e.State & DrawItemState.Selected) !=
DrawItemState.Selected)
{
//選択されていない時
switch (e.Index % 3)
{
case 0:
b = new SolidBrush(Color.Red);
break;
case 1:
b = new SolidBrush(Color.Blue);
break;
case 2:
b = new SolidBrush(Color.Green);
break;
}
}
else
{
//選択されている時はそのままの前景色を使う
b = new SolidBrush(e.ForeColor);
}
//描画する文字列の取得
string txt = ((ListBox) sender).Items[e.Index].ToString();
//文字列の描画
e.Graphics.DrawString(txt, e.Font, b, e.Bounds);
//後始末
b.Dispose();
//フォーカスを示す四角形を描画
e.DrawFocusRectangle();
}
-----------------------------------------------
を参考にしてForm1に
private: System::Void ListBox1_DrawItem(System::Object^ sender, System::Windows::Forms::DrawItemEventArgs^ e)
{
//背景を描画する
//項目が選択されている時は強調表示される
e->DrawBackground();
//文字を描画する色の選択
}
と書いてみたのですが、そのあとどうすればよいかわかりません。
わかる方、回答お願いします。
No.1ベストアンサー
- 回答日時:
ある程度の法則性はあるのでC# → C++/CLIはそれほど難しい置き換えじゃないはずですが。
1.new → gcnew
2.gcnewで確保するオブジェクトを宣言するときは^を付けて参照型に
3.メンバー参照の.を->に(第1階層だけ)
4.ネームスペース参照の.を::に
#他に何かあったかな……
もちろん単純に置き換えではうまく行かないケースもあるはずなのでそこはケースバイケースで。
この回答への補足
回答ありがとうございます。
参考にさせてもらいます。
とりあえず
Brush b = null;
でコンパイルエラーになります。
C3622: 'System::Drawing::Brush': 'abstract' として宣言されたクラスをインスタンス生成することはできません
C2065: 'null' : 定義されていない識別子です。
どういうことでしょうか
No.2
- 回答日時:
> Brush b = null;
> でコンパイルエラーになります。
これは後に続くswitch()の中と合わせて1と2の複合です。
なお、nullはNULLとしてください。
No.3
- 回答日時:
ちょっと変なので修正。
ここは、後ろのswitch内でオブジェクトを生成する部分が1に該当するため、遡って2のケースが適用されます。
null→NULLとするのは#2で書いた通り。
No.4
- 回答日時:
こんばんは。
このオーナードローは、様々なコントロールをカバーしているので、モノによっては使わないフラグもあります。
その他、選択はされているが、キーボード操作によってフォーカスが別のアイテムに逃げている、コントロール自体がディセーブルされた、特定のアイテムだけがディセーブルされたなど、色々な状況があり、これ等はモノによって違いがありますので、取り出したに確認し、順を追って描きあげて行きます。
一通り描いた後は、アイテムやコントロールをディセーブルにしたり、アイテムを選択したままタブを押して、フォーカスを逃がす等、色々と確認して下さい。
また、再描画が必要になるとアイテムが一つも存在しない時ですら、飛び込んでくるので其の点も要注意です。
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;
}
回答ありがとうございます。
うまく自分のやりたいことができました。
オーナードローするときはいろいろ考えたほうが良いのですね。
とても勉強になりました。
No.5
- 回答日時:
No.6
- 回答日時:
・・・ほぼそのままだと思うんだけど
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();
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- JavaScript セレクトボックスを2つ選択してメッセージなどを表示するには。~運賃検索プログラムを完成させたい~ 1 2022/07/22 11:10
- マンガ・コミック 漫画の練習方について 1 2022/06/06 19:26
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
- その他(Microsoft Office) ワードのマクロについて教えてください。 1 2023/01/21 16:01
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2022/04/01 12:11
- JavaScript セレクトボックスを2つ設けて選択して初めてメッセを表示 1 2022/07/27 12:15
- JavaScript switch文のswitch(n)の部分を複数の値にするか、if文に変えてほしいです。 1 2022/07/27 17:18
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PCで「使用可能な場合はグラフ...
-
TextBoxに文字を書いても表示さ...
-
NVIDIAのシェーダーキャッシュ
-
[VB.net] DataGridViewの列ヘッ...
-
ブレゼンハムのアルゴリズムに...
-
vc++のpictureboxにopenGLの画...
-
画像の印刷について
-
MFC ビットマップ描画で残像が残る
-
VB6のform Load
-
VB6,リストボックスの特定行の...
-
UpdateData( FALSE); による文...
-
ワード2019 描画ツールの書式が...
-
C++にて、塗りつぶされた円を描...
-
ダイアログベースの再描画について
-
WM_PAINTとWM_MOVEで同じ事をし...
-
Windowのちらつき防止
-
FlexGridの一部のみ表示を更新...
-
InvalidateRectの使い方について
-
C言語(dxlib)のDrawboxについ...
-
LineToやMoveToにて描画した線...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB6,リストボックスの特定行の...
-
[VB.net] DataGridViewの列ヘッ...
-
NVIDIAのシェーダーキャッシュ
-
MFCでOnPaintのタイミング
-
TextBoxに文字を書いても表示さ...
-
word
-
UpdateData( FALSE); による文...
-
VC++プログラムをつかったBMP画...
-
InvalidateRectの使い方について
-
OneNote 2010 文字と描画がずれる
-
StretchBlt関数について
-
C# ラバーバンドの描画を快適に...
-
エクセルでガンチャートを作成...
-
C++にて、塗りつぶされた円を描...
-
VBAにGDI+を参照させる方法
-
GDI+で高速な描画
-
MFC DrawText 背景色とフォント
-
FlexGridの一部のみ表示を更新...
-
MFCのタイマーのつかい方を教え...
-
Labelの文字をスクロールする際...
おすすめ情報