梅林日記

雑用系プログラマの趣味とお仕事

目次

Blog 利用状況

ニュース

資格

MCAD OCP

書庫

日記カテゴリ

WM_PAINTを使ったTextBoxのカスタム描画

数日前のえムナウさんのエントリ「TextBoxを自分で描画する」を読みました。

 

TextBoxに入力もしくはデータバインドしたデータを、数値や日付データとして

フォーマットして表示するという機能は以前から必要としておりまして、これまでは

Textプロパティをoverrideするという無理やりな方式を採用していました。

 

できればTextプロパティはそのままで、表示するデータだけを変えるようにしたいと思っていたので

これはいい、と早速試してみたのですが、書いてあるとおりSetStyleやRecreateHandleを記述しても

どうしてもフォーカスがあるときと無いときでフォントの大きさが変わってしまいます。

 

色々調べた結果、WM_PAINTメッセージを捕まえてCreateGraphicsで作成したGraphicsオブジェクトに

文字列の描画を行う方式に落ち着きそうです。


namespace Umebayashi.Framework.Windows.Forms
{
    public partial class UmeTextBox : TextBox
    {
        public UmeTextBox()
        {
            InitializeComponent();
        }

        private const int WM_PAINT = 0x000F;

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            switch (m.Msg)
            {
                case WM_PAINT:
                    //フォーカスがある状態ではフォーマットしない
                    if (!Focused)
                    {
                        DrawText();
                    }
                    break;
                default:
                    break;
            }
        }

        private void DrawText()
        {
            TextFormatFlags tff = TextFormatFlags.VerticalCenter;
            switch (this.TextAlign)
            {
                case HorizontalAlignment.Center:
                    tff |= TextFormatFlags.HorizontalCenter;
                    break;
                case HorizontalAlignment.Left:
                    tff |= TextFormatFlags.Left;
                    break;
                case HorizontalAlignment.Right:
                    tff |= TextFormatFlags.Right;
                    break;
            }
            if (this.Multiline)
            {
                tff |= TextFormatFlags.WordBreak;
            }

            using (Graphics g = CreateGraphics())
            using (Brush backBrush = new SolidBrush(this.BackColor))
            {
                //BackColorで背景を塗りつぶす。
                //これをしないとフォーマット前後の文字列がダブって表示される。
                g.FillRectangle(backBrush, this.ClientRectangle);

                DateTime dtVal;
                decimal dcVal;
                if (DateTime.TryParse(this.Text, out dtVal))
                {
                    TextRenderer.DrawText(g, dtVal.ToString("yyyy/MM/dd"),
                        this.Font, this.ClientRectangle, this.ForeColor, tff);
                }
                else if (decimal.TryParse(this.Text, out dcVal))
                {
                    TextRenderer.DrawText(g, dcVal.ToString("#,##0"),
                        this.Font, this.ClientRectangle, this.ForeColor, tff);
                }
                else
                {
                    TextRenderer.DrawText(g, this.Text,
                        this.Font, this.ClientRectangle, this.ForeColor, tff);
                }
            }
        }
    }
}

投稿日時 : 2007年2月15日 0:03

コメントを追加

# TextBoxを自分で描画する2 2007/02/15 10:03 えムナウ Blog

TextBoxを自分で描画する2

# re: WM_PAINTを使ったTextBoxのカスタム描画 2007/06/01 16:42 通りすがりのプログラマ

ありがとうございます。
参考にさせていただきました。

# re: WM_PAINTを使ったTextBoxのカスタム描画 2017/05/06 18:32 Teddy

With millions of players playing this game on iPhone, you are sure to have unlimited amounts of fun with Diamond Space - Jewel Dash. http://fun-torrent.ru Create and share your own menus and actions - both for proximity and when the phone rings - using Applescript, key and mouse emulation.

# re: WM_PAINTを使ったTextBoxのカスタム描画 2017/07/06 21:55 オースティン


1枚のカードを勉強するときにクラッシュする問題を修正し、オプションをもっと勉強し始めました。 http://getfreegamesplease.usエンターテイメントカンパニーは、世界でも有??数のライセンシングおよびリテールマーチャンダイジング機関の1つです。

タイトル  
名前  
URL
コメント