App Programming/C#2007. 6. 4. 09:34
 

 SetStyle 이용하여 애니메이션 출력



Picture 박스에 그려서 그림판 기능 구현

Picture 박스에 그려서 sin 파형 구현



--------------------------------------------------------------------------------------------------------------
닷넷 3.0 으로 업그레이드??
--------------------------------------------------------------------------------------------------------------
백그라운드 투명 제거
--------------------------------------------------------------------------------------------------------------

public 생성자()
{

            // 이 호출은 Windows.Forms Form 디자이너에 필요합니다.

            InitializeComponent();

            // TODO: InitComponent를 호출한 다음 초기화 작업을 추가합니다.

            this.SetStyle(ControlStyles.DoubleBuffer,true);     // 1
            this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);    // 2
            this.SetStyle(ControlStyles.UserPaint,true);     // 3
            this.UpdateStyles();
}

-------------------------------------------------------------------------------------------
dc는 폼의 dc를 바로 얻은 것이 겠지요?
Bitmap bitOffScreen = new Bitmap(크기를 넣어줍니다);

이런 식으로 그래픽 객체(g)를 하나 만들어서
Graphics g = Graphics.FromImage(bitOffScreen);

g에 그림을 그립니다(즉 bitOffScreen에 그려지겠지요)
그리고 dc에 bitOffScreen을 그리면 됩니다.

-------------------------------------------------------------------------------------------

http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=17&MAEULNo=8&no=47587&ref=47569

-------------------------------------------------------------------------------------------
public void EnableDoubleBuffering()
{
   // Set the value of the double-buffering style bits to true.
   this.SetStyle(ControlStyles.DoubleBuffer |
      ControlStyles.UserPaint |
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}
------------------------------------------------------------------------------------------------


기존의 Panel 을 (UserControl 에서 상속된) 사용자 정의 컨트롤로 대체하고,
사용자 정의 컨트롤의 OnPaint 메소드를 override 하였습니다.
그리고, 생성자에서 SetStyle 를 사용하였습니다.
일부러 상속된 Panel 을 사용하지 않고, 상속된 UserControl 을 사용한 것은
그것이 다른 UserControl 의 구성요소이기 때문입니다.


        public BndCompareCustomTreeDrawingControl()
        {
            // 이 호출은 Windows.Forms Form 디자이너에 필요합니다.
            InitializeComponent();

            // TODO: InitForm을 호출한 다음 초기화 작업을 추가합니다.
            // 화면 깜빡임 없이 그리도록 한다.
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.UserPaint, true);
        }
       
        /// <summary>
        /// 화면 깜빡임 없이 그리도록 한다.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            if(m_BndCompareView != null)
            {
                Log.LogInfo(" 그리기 범위["+(m_BndCompareView.VScrollBar.Value)+"~"+(m_BndCompareView.VScrollBar.Value + m_Drawing_Count - 1)+"], 전체 범위[0~"+(m_BndCompareView.VScrollBar.Maximum)+"]");
                for(int i = m_BndCompareView.VScrollBar.Value, j = 0; i < m_BndCompareView.VisibleNodeList.Count && j < m_Drawing_Count; ++i, ++j)
                {
                    ((BndCompareNode) m_BndCompareView.VisibleNodeList[i]).PaintNode(e.Graphics, 0, j * 23, this.Size.Width, 23);
                }
            }
        }

이 컨트롤은 윈도탐색기 화면처럼
경우에 따라 상당히 많은 데이터 노드들을 가질 수 있습니다.
OnPaint 를 override 하여, 화면에 보이는 노드들만 선택적으로 그리므로
데이터가 많더라도 느려지지 않는 장점이 있습니다.

문제는 스크롤 바를 직접 관리하다보니
상당히 헷갈려서 스크롤 관련 코드만 하루종일 걸렸습니다.
(휴~ 그나마 스크롤바 중 하나는 절대 안쓰니까, 이만하길 다행이지...)

------------------------------------------------------------------------------------------------
Windows Forms 의 GDI+는 자동으로 더블 버퍼링을 지원합니다.
SetStyle 했을때와 안했을때를 마우스로 그림그릴경우에 비교해보면 엄청난 차이가 있습니다. 화면의 깜빡임이 거의 없어지죠.
SetStyle 메서드의 매개변수인 ControlStyles 열거형의 값을 적절히 설정하면 GDI+의 더블 버퍼링을 지원받을수 있습니다.
아래에 있는 세개의 플래그들을 설정해주어야 합니다. 아래의 코드는 폼의 생성자나 Load 이벤트 메서드에 추가하면 됩니다.

SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
 혹은
 아래처럼 한줄로 할수도 있겠죠... 플래그 값이므로...
SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint , true);

아래는 ControlStyles 열거형 멤버의 설명입니다.
DoubleBuffer:
    모든 그리기 연산들이 하나의 버퍼 안에서 수행되게 하고, 연산들이 완료되면 그 결과를 화면에 그린다.
AllPaintingWmPaint:
    윈도우의 배경이 개별적인 연산으로 그려지지 않게 한다. UserPaint를 true로 설정했을 때에만 이 값을 사용해야 한다.
UserPaint:
    컨트롤이 자신을 그리게 한다.

더블 버퍼링을 직접 구현하는것보다 성능면에서 훨씬 우위에 있습니다(최적 코드로 구성되어있으므로...). 직접 구현해보는것도 좋겠지만 SetStyle을 사용하시는게 아마 성능면에서 나을겁니다.





 



Posted by BAGE