본문 바로가기
C#

C#08. 메모리, 마우스 및 스크롤

by 정양섭 2022. 3. 8.

  이제 지금까지 만든 Paint 프로그램에 마우스를 이용하여 객체를 그리는 기능을 추가해보겠습니다.
  객체를 그리는 방법은 두가지입니다. mspaint 처럼 Image에 직접 그림을 그려 그 그림을 저장하는 형태와 PhotoShop처럼 각 그리기 객체를 내부적으로 메모리를 관리하는 형태(Vector형태로 관리)가 있습니다. 여기서는 내부적으로 메모리를 관리하는 형태로 구성해보도록 하겠습니다.

  프로젝트 이름에(여기서는 Paint) 마우스 오른쪽버튼을 눌러 생성된 팝업 메뉴의 추가의 부메뉴 클래스를 선택하면 다음과 같은 대화 상자가 생성됩니다.

  이름에 DrawObj.cs를 입력하고 추가를 선택합니다.
  같은 방식으로 DrawLine.cs, DrawRect.cs, DrawEllipse.cs, ObjList.cs를 각각 만듭니다.

  DrawObj
    public class DrawObj
    {
        public Rectangle rectPos;
        public Color colorLine = Color.Black;
        public Color colorFace = Color.Red;

        virtual public void Draw(Graphics g)
        {
        }
    }
   DrawObj는 그림 객체의 Base 객체로 기본적으로 가져야 할 정보를 구성합니다.
   여기서는 사각형 위치와 선, 면 색상만 두었습니다. virtual 로 Draw 함수를 하나 구성하였습니다. 이후에 설명할 예정이니 virtual로 선언한 이 함수를 기억하기 바랍니다.

   DrawLine
    public class DrawLine : DrawObj
    {
        override public void Draw(Graphics g)
        {
            Pen pen = new Pen(base.colorLine);
             g.DrawLine(pen, base.rectPos.Left, base.rectPos.Top, base.rectPos.Right, base.rectPos.Bottom);
        }
    }
  DrawLine은 DrawObj로부터 상속 받아 구성합니다. 앞에서 virtual 로 Draw 함수를 여기서는 override로 구성하였습니다. DrawRect와 DrawEllipse는 그리는 내용만 드르므로 작성해 보기 바랍니다.

  ObjList
     class ObjList
    {
        ArrayList objList = new ArrayList();
        public bool Add(DrawObj obj)
        {
            if(objList==null)
                return false;
            this.objList.Add(obj);
            return true;
        }

 

        public void Draw(Graphics g)
        {
            if(this.objList==null)
                return;

            DrawObj obj;
            int nCount = objList.Count;
            for (int i = 0; i < nCount; i++)
            {
                obj = (DrawObj)objList[i];
                obj.Draw(g);
            } 
        }
    }

  여기서 Draw를 보겠습니다. 그냥 단순히 DrawObj로 Draw함수를 호출한다(obj.Draw(g)). 생성시 각 Class로 생성하여 ArrayList에 넣고, 이렇게 호출하면 알아서 선이면 선으로 사각형이면 사각형으로 원이면 원으로 알아서 그려집니다. 이것은 루틴을 아주 많이 줄여 줍니다. 여기서 만약 이기능을 사용하지 않는다면 조건에 따라 각 Class에 맞추어  Draw함수를 호출하도록 조건문이 들어 가야 합니다. 만약 지금처럼 객체가 3개이면 별로 많이 늘어나지 않으나, 많을 경우 아주 많이 늘어 나게 됩니다.
   이기능을 가능하게 해주는 것이 override 기능입니다. override 기능은 base class에 virtual 로 선언한 함수를 class에서 override로 선언하여 재구성하고, base class함수를 호출하면 알아서 실제 class함수가 호출되는 기능입니다.

마우스 기능 추가
마우스 기능을 추가하고자 하는 Form을 열어 속성에서 이벤트 버튼을 선택하여 MouseDown과 MouseUp을 더블클릭합니다.


MouseDown
         private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.bMousePressed = true;
                this.mousePoint.X = e.X;
                this.mousePoint.Y = e.Y;
            }
        }
마우스가 눌러졌다는것과 마우스 위치를 저장합니다.
MouseUp   
         private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (this.bMousePressed == false)
                    return;
                thsi.bMousePressed = false;
                DrawObj obj = null;
                switch (this.drawKind)
                {
                    case DrawKind.Line:
                        obj = new DrawLine();
                        break;

                    case DrawKind.Rectangle:
                        obj = new DrawRect();
                        break;

                    case DrawKind.Ellipse:
                        obj = new DrawEllipse();
                        break;

                    default:
                        return;
                }
                if (obj == null)
                    return;

                obj.rectPos = new Rectangle(this.mousePoint.X - this.AutoScrollPosition.X, this.mousePoint.Y -
                                               this.AutoScrollPosition.Y, e.X - this.mousePoint.X, e.Y - this.mousePoint.Y);
                if (this.objList == null)
                    return;

                this.objList.Add(obj);
                Invalidate();
            }
        }

그리기 종류에 따라 객체를 생성하여 objList에 추가한 후 화면을 새로 그립니다.

 

Scroll 기능 추가

속성에서 AutoScroll를 True로 변경합니다.
그림 크기로 AutoScrollMinSize를 설정합니다.            
this.AutoScrollMinSize = this.imageSize;
그리기전 스크롤 위치를 설정합니다.
        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            if (this.objList == null)
                return;
            e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
            this.objList.Draw(e.Graphics);
        }

예제 프로그램 다운로드

Paint_MouseScroll.zip
0.02MB

 

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

C#10. MDI 및 인쇄하기  (0) 2022.03.08
C#09. 파일 지원  (0) 2022.03.08
C#07. 대화상자  (0) 2022.03.08
C#06. GDI+ 및 깜박임 문제 해결  (0) 2022.03.08
C#05. 메뉴 및 툴바 지원  (0) 2022.03.08