반응형

방법.. 잘 읽어봐라..-_-;


Form 페이지 만든 후 Form의 Designer.cs 페이지에서 해당프로젝트.Controls.TextBoxExt() 라고 InitializeComponent와 

제일 아래 private Head1Ton.Dev.Controls.TextBoxExt txtBoxExt1; 이라고 변경해줘야만 한다.





텍스트 박스에 값을 입력하지 않으면 배경에 특정 메시지를 보여주고, 값을 입력하면 보이지 않게 해달라는 요청을 받았습니다.

 

그런데!!

 

텍스트박스는 OnPaint를 기본적으로 쉽게 사용할 수 없습니다. SetStyle 메서드에서 UserPaint 플래그를 설정하면 가능하지만, 글씨 같은 부분도 모두 처리해 줘야되기 때문에 여간 번거로운게 아닙니다. 제가 원하는건 오직배경에 뭔가 처리!’ 그것 뿐이라구요..ㅠㅡㅠ

 

그래서 WndProc 를 재정의해서 이벤트를 받아오는 방법을 사용했습니다. 주의라고 까진 아니지만, 유심히 보실 부분은 WM_KILLFOCUS 도 처리해주고 있는것인데요. 텍스트 박스를 멀티라인 지원으로 해놓으면, WM_PAINT 가 발생을 하지 않더군요. 그래서 WM_PAINT 에서도 처리를 해주었습니다.

 

using System;

using System.Drawing;

using System.Windows.Forms;

 

namespace TextBoxPaintSample.Controls

{

    public class TextBoxExt : TextBox

    {

        private string waterMarkText = string.Empty; // 워터마크로 사용할 문자열

        private Color waterMarkColor = Color.Gray;   // 워터마크로 사용할 문자색

 

        protected override void WndProc(ref Message m)

        {

            // base.WndProc 중복 호출을 피하기 위해서

            bool isCallAlready = false;

 

            // WM_PAINT 메세지를 받아서 처리

            if (m.Msg == 0x000F) // WM_PAINT = 0x000F

            {

                // 원래 처리해야될 로직을 먼저 호출해서 처리해줌

                base.WndProc(ref m);

                isCallAlready = true;

 

                DrawWaterMarkText();

            }

            // Multiline == true 일때는 포커스 빠질때 WM_PAINT가 발생 안하므로

            else if (m.Msg == 0x0008 && this.Multiline) // WM_KILLFOCUS = 0x0008

            {

                DrawWaterMarkText();

            }

 

            if (false == isCallAlready)

                base.WndProc(ref m);

        }

 

        // 텍스트박스의 크기를 계산해서 워터마크를 그려줌

        private void DrawWaterMarkText()

        {

            if (string.IsNullOrEmpty(this.Text) &&

                false == string.IsNullOrEmpty(this.WaterMarkText) &&

                this.IsHandleCreated &&

                false == this.Focused &&

                this.Visible)

            {

                using (Graphics g = Graphics.FromHwnd(this.Handle))

                {

                    // 텍스트의 vertical 정렬을 하기 위한 계산들

                    StringFormat sf = new StringFormat();

                    float textHeight = g.MeasureString(this.WaterMarkText, this.Font, this.Width, sf).Height;

                    float textY = ((float)this.Height - textHeight) / (float)2.0;

                    RectangleF bounds = new RectangleF(

                        0, textY, (float)this.Width, (float)this.Height - (textY * (float)2.0));

 

                    g.DrawString(this.WaterMarkText, this.Font, new SolidBrush(this.WaterMarkColor),bounds, sf);

                }

            }

        }

 

        public string WaterMarkText

        {

            get { return waterMarkText; }

            set { waterMarkText = value; }

        }

 

        public Color WaterMarkColor

        {

            get { return waterMarkColor; }

            set { waterMarkColor = value; }

        }

 

    }

}


 

샘플 결과

사용자 삽입 이미지

 

이러한 코드를 바탕으로 텍스트 박스의 배경으로 이미지를 넣는다던지 하는 처리도 가능하리라 생각됩니다.

 

소스코드 전체를 첨부합니다. VS2005에서 작성 및 테스트되었습니다.
 

 


ps. 사실, 이 포스트의 내용은 제가 원래 작성하고자 했던 내용은 아닙니다만, 문제해결의 과정을, 혹은 진짜 이 내용이 필요하신분을 위해서 먼저 작성하였습니다. 다음 포스트에서는 TextBox를 상속받을 수 없는경우, 즉 다른 사람이 만든 TextBox에서 컨트롤만 얻어올 수 있을때의 대처 방법을 포스팅 하겠습니다.


반응형

'Program > C#' 카테고리의 다른 글

주사위놀이  (0) 2010.02.09
Silent Install of MS .Net Framework Version 2  (0) 2010.02.05
윈도우 폼 간 도킹 기능  (0) 2010.01.26
윈폼 파일 드레그하기  (0) 2010.01.26
C# 초보자분들을 위한 기초강좌  (0) 2010.01.24

+ Recent posts