C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: テキストエディタ作成-新たな問題点について


(過去ログ 135 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■79736 / inTopicNo.1)  テキストエディタ作成-新たな問題点について
  
□投稿者/ みう (4回)-(2016/05/10(Tue) 20:40:50)

分類:[.NET 全般] 

昨日からの質問に回答していただいた皆様のおかげでテキストボックスの自前描画ができました。
その節についてはありがとうございました。

さて、新たな問題点ですが、自前描画すると「カーソル位置が文字数が増えるごとにずれる」という問題が発生しました。
アルファベットのgの形を見ると自前描画した文字は正常なフォント・大きさでしたが、その下に描画されたものは少し小さく、アルファベットのgの形から全く別のフォントであることがわかりました(文字列を選択するとわかります)。
自前描画しない場合はこの勝手に描画される文字列も正常なフォントなのですが...

コードを載せるので問題解決の糸口となるような情報をお願いいたします。

'==================================================
'Class1.vb
'==================================================
Public Class MyTextBox
    Inherits TextBox

    Public Sub New()
        '自前描画有効化
        Me.SetStyle(ControlStyles.UserPaint, True)
    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        '緑のブラシを設定
        Dim g As New System.Drawing.SolidBrush(Color.Green)
        '文字列を描画する
        e.Graphics.DrawString(Me.Text, Me.Font, g, 0, 0)
        g.Dispose()
    End Sub

    Protected Overrides Sub OnTextChanged(e As System.EventArgs)
        MyBase.OnTextChanged(e)
        'これをしないと反映されない
        Me.Invalidate()
    End Sub
End Class

'==================================================
'Form1.vb
'==================================================
Public Class Form1

    Public Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim mtext As New MyTextBox
        '複数行入力可能に
        mtext.Multiline = True
        '複数行入力で折り返さない
        mtext.WordWrap = False
        'スクロールバーをつける
        mtext.ScrollBars = ScrollBars.Both
        'フォントの設定
        mtext.Font = New Font("MS ゴシック", 12.0)
        '座標指定
        mtext.Location = New Point(14, 14)
        'サイズ指定
        mtext.Size = New Size(800, 200)

        Me.Controls.Add(mtext)
    End Sub

End Class

引用返信 編集キー/
■79738 / inTopicNo.2)  Re[1]: テキストエディタ作成-新たな問題点について
□投稿者/ kiku (97回)-(2016/05/11(Wed) 09:28:07)
TextBoxの内部実装に関しては詳細は把握していない状態であるため、
推定での回答をします。

おそらく、カーソル表示、カーソル制御、カーソル表示、
文字表示、文字削除、文字挿入などの機能は、
OnPaintだけで実現しているものではなく、
キー関連のイベントやマウス関連のイベント(?)なども
関連していると思われます。

試しに下記のようにキーイベントのデフォルト動作を
させない処理にしてみてください。
理解が進むと思います。

    Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs)
        'MyBase.OnKeyPress(e)
        System.Diagnostics.Debug.WriteLine("OnKeyPress発生" & e.KeyChar)
        Me.Text += e.KeyChar
        e.Handled = True 'ここでTextBoxのデフォルトの動作を禁止する
        Me.Invalidate()
    End Sub

ようするにどうすればよいかということですが、
自前の表示を実装するということは
カーソル制御も自前で行うということになるかと思います。

大変になると思います。

引用返信 編集キー/
■79746 / inTopicNo.3)  Re[2]: テキストエディタ作成-新たな問題点について
□投稿者/ みう (5回)-(2016/05/11(Wed) 18:17:04)
No79738 (kiku さん) に返信
> TextBoxの内部実装に関しては詳細は把握していない状態であるため、
> 推定での回答をします。
> 
> おそらく、カーソル表示、カーソル制御、カーソル表示、
> 文字表示、文字削除、文字挿入などの機能は、
> OnPaintだけで実現しているものではなく、
> キー関連のイベントやマウス関連のイベント(?)なども
> 関連していると思われます。
> 
> 試しに下記のようにキーイベントのデフォルト動作を
> させない処理にしてみてください。
> 理解が進むと思います。
> 
>     Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs)
>         'MyBase.OnKeyPress(e)
>         System.Diagnostics.Debug.WriteLine("OnKeyPress発生" & e.KeyChar)
>         Me.Text += e.KeyChar
>         e.Handled = True 'ここでTextBoxのデフォルトの動作を禁止する
>         Me.Invalidate()
>     End Sub
> 
> ようするにどうすればよいかということですが、
> 自前の表示を実装するということは
> カーソル制御も自前で行うということになるかと思います。
> 
> 大変になると思います。

kiku 様や前トピックの回答者様のおかげで目的のものが作れました。
本当にありがとうございました。

他の方の参考になればとも思ったので載せていきます。
「//」を検出し、文字色を緑にして描画するものです。

Public Class TextBox_CommentOut
    Inherits System.Windows.Forms.TextBox

    Private Const WM_PAINT As Integer = &HF

    'コンストラクタ
    Public Sub New()
        '複数行入力可能に
        Me.Multiline = True
        '複数行入力で折り返さない
        Me.WordWrap = False
        'スクロールバーをつける
        Me.ScrollBars = ScrollBars.Both
        'フォントの設定
        Me.Font = New Font("MS ゴシック", 12.0)

    End Sub

    'Windowsメッセージを横取りします
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        MyBase.WndProc(m)
        Select Case m.Msg
            Case WM_PAINT
                Me.SetStyle(ControlStyles.UserPaint, True)
                My_DrawText_()
                Me.SetStyle(ControlStyles.UserPaint, False)
        End Select
    End Sub

    '描画
    Private Sub My_DrawText_()

        If Me.TextLength = 0 Then
            Return
        End If

        Dim MyTextPos As Point
        Dim i As Integer
        Dim j As Integer = 0

        For i = 0 To Me.TextLength - 1
            'i文字目の文字位置を取得
            MyTextPos = Me.GetPositionFromCharIndex(i)

            '描画範囲から外れるなら描画しない(X)
            If MyTextPos.X > 0 And MyTextPos.X < Me.Size.Width Then

                '描画範囲から外れるなら描画しない(Y)
                If MyTextPos.Y > 0 Then
                    If MyTextPos.Y > Me.Size.Height Then
                        Exit For
                    Else
                        Select Case j
                            '0:通常
                            '1:コメントアウト

                            '------通常状態------
                            Case 0
                                Select Case Me.Text(i)
                                    Case "/"
                                        '最後の文字じゃない かつ 次も改行ならコメントアウト
                                        If i < Me.TextLength - 1 Then
                                            If Me.Text(i + 1) = "/" Then
                                                j = 1
                                                System.Windows.Forms.TextRenderer.DrawText(Me.CreateGraphics, Me.Text(i), Me.Font, New Point(-3, 0) + MyTextPos, Color.Green)
                                            End If
                                        End If
                                End Select

                                '------コメントアウト------
                            Case 1
                                Select Case Me.Text(i)
                                    '改行が来るまではコメント
                                    Case vbCr, vbCrLf
                                        j = 0
                                    Case Else
                                        System.Windows.Forms.TextRenderer.DrawText(Me.CreateGraphics, Me.Text(i), Me.Font, New Point(-3, 0) + MyTextPos, Color.Green)
                                End Select
                        End Select



                    End If
                End If
            End If
        Next

    End Sub

    Protected Overrides Sub OnTextChanged(e As System.EventArgs)
        MyBase.OnTextChanged(e)
        My_DrawText_()
    End Sub
End Class


引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -