描画した文字の色替え不可について

タグの編集
投稿者   (高校生) 投稿日時 2016/8/11 19:59:28
先ほども質問した者ですが、様々な方法をやっても出来なかったので、再度来てしまいました。
すみません
ピクチャーボックスに文字を描画するというのは.DrawStringメソッドを使って縦書きにしています。
縦書きの表示についてはこちらのサイトを参考にして行いました。
http://dobon.net/vb/dotnet/graphics/drawstring.html
この縦書きで表示されている文字の色つまりForeColorをカラーダイアログで選んだ色に変更したいのですが、変更ができません。
BackColorは変更が可能なのですが、なぜかForeColorは駄目なようです。
 Private Sub ColorH_Click(ByVal sender As ObjectByVal e As System.Windows.Forms.MouseEventArgs)
        Dim cd As New ColorDialog()
        Dim bcc As SolidBrush = New SolidBrush(cd.Color)
        cd.Color = bcc.Color
        bcc.Color = mozi.ForeColor
        cd.AnyColor = False '仮 
        cd.AllowFullOpen = True
        cd.SolidColorOnly = True
        cd.ShowHelp = False
        If cd.ShowDialog() = DialogResult.OK Then
            bcc.Color = cd.Color
            mozi.ForeColor = bcc.Color
        End If
    End Sub

moziというのはテキストボックスで入力した文字を描画したピクチャーボックスです。
 Dim mozi As PictureBox
 Me.mozi = New PictureBox()
2回目とずうずうしくてすみませんが、回答できる方がいましたらよろしくお願いします。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2016/8/11 20:17:28
「色を選択するところ」ではなく、
「文字を描画しているところ」のコードを提示してください。

> BackColorは変更が可能なのですが、なぜかForeColorは駄目なようです。
Label や TextBox とは異なり、PictureBox 自身は、
文字列を表示する機能を持たないため、ForeColor を使いません。
(そのため ForeColor プロパティは、開発ツールからは見えないよう非表示に設定されています)

選んだ色を保持しておく場所として ForeColor プロパティを使うのは構いませんが、
その場合、「文字を描画しているところ」のコードを修正し、ForeColor を用いるように
差し替える必要があります。

> 変更ができません。
色を変更するというよりは、もともと描いてあった縦書き文字列をクリアして
新しい色の縦書き文字列で描きなおすという処理になります。

投稿者   (高校生) 投稿日時 2016/8/11 20:21:17
文字を描画しているところのコードはこちらです。
   If Rtext.Text = "*" Then
            MsgBox("テキストを入力してください")
        Else
            If Mmax < 50 Then
                Te = Rtext.Text
                Me.mozi = New PictureBox()
                Me.mozi.Name = "Text1"
                Me.mozi.Text = Te
                Me.mozi.AutoSize = False
                Me.mozi.Size = New Size(150, Rtext.TextLength * 40)

                '描画先とするImageオブジェクトを作成する 
                Dim canvas As New Bitmap(Rtext.Width, Rtext.Height)
                'ImageオブジェクトのGraphicsオブジェクトを作成する 
                Dim g As Graphics = Graphics.FromImage(canvas)

                Dim drawString As String = Rtext.Text
                'Fontオブジェクトの作成(太字にする) 
                Dim fnt As New Font("@ 明朝", 24, FontStyle.Bold)
                'StringFormatを作成 
                Dim sf As New StringFormat()
                '縦書きにする 
                sf.FormatFlags = StringFormatFlags.DirectionVertical
                '縦書きにして、右から左に表示する 
                ''sf.FormatFlags = StringFormatFlags.DirectionVertical Or _ 
                'StringFormatFlags.DirectionRightToLeft() 
                fnt = Rtext.Font
                Dim color As Color
                Dim bc As SolidBrush = New SolidBrush(Rtext.ForeColor)

                '文字を表示 
                g.DrawString(drawString, fnt, bc, 0.0F, 0.0F, sf)

                'リソースを解放する 
                sf.Dispose()
                fnt.Dispose()
                g.Dispose()

                'PictureBox1に表示する 
                mozi.Image = canvas
                Me.mozi.BackColor = Color.Transparent
                mozi.ContextMenuStrip = ContextMenuStrip1
                AddHandler mozi.MouseDown, AddressOf mozi_MouseDown
                AddHandler mozi.MouseMove, AddressOf mozi_MouseMove
                AddHandler mozi.MouseUp, AddressOf mozi_MouseUp
                AddHandler mozi.Click, AddressOf mozi_Click
                AddHandler mozi.DoubleClick, AddressOf mozi_DoubleClick
                Panel1.Controls.Add(Me.mozi)
                mozi.BringToFront()
                Rtext.Clear()
                Mmax = Mmax + 1
            Else
                MsgBox("これ以上配置できません", 16)
            End If
        End If
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2016/8/11 22:59:30
> mozi.Image = canvas
> Me.mozi.BackColor = Color.Transparent

mozi だったり Me.mozi だったりと、表記が混在していますが、
この 2 つは同じ変数でしょうか?
(前者がローカル変数、後者がフィールド変数という可能性もありますが…)



> 文字を描画しているところのコードはこちらです。
ざっくり書くと、
 Dim canvas As New Bitmap(Rtext.Width, Rtext.Height)
 Dim g As Graphics = Graphics.FromImage(canvas)
 Dim bc As SolidBrush = New SolidBrush(Rtext.ForeColor)
 g.DrawString(drawString, fnt, bc, 0.0F, 0.0F, sf)
 mozi.Image = canvas
ということですよね。
文字色を司っているのは、上記でいうと変数 bc にあたります。


ですから、文字色を変えたいのであれば、
 Dim oldImage As Image = mozi.Image
 Dim newImage As New Bitmap(oldImage.Width, oldImage.Height)
 Dim g As Graphics = Graphics.FromImage(canvas)
 Dim bc As SolidBrush = New SolidBrush(mozi.ForeColor)   '★ 
 g.DrawString(drawString, fnt, bc, 0.0F, 0.0F, sf)
 mozi.Image = newCanvas
 oldImage.Dispose()
 fnt.Dispose()
 bc.Dispose()
 sf.Dispose()
 g.Dispose()
という感じです。


注意するとすれば、
> Me.mozi = New PictureBox()
のように、新しい PictureBox をもう一つ作るのではなく、
すでに作成済みの PictureBox (すなわち mozi)に対して
処理を行う必要がある、ということです。


もし、この処理が何度も呼ばれていて、Panel 上に複数の PictureBox が
配置されているのであれば、それらの`PictureBox それぞれに対して
新しい Bitmap を用意し、以前と同じ文字列を、新しい色で描画して
割り当てていく必要がありますね。
投稿者   (高校生) 投稿日時 2016/8/12 19:26:29
文字の色替えをすることができました。
本当にありがとうございました。