2011. 7. 13. 02:20

바코드를 찍어주는 프로그램을 만든 적이 있습니다.

GDI+로 출력을 했었습니다.

문제의 그화면

 

 

문제의 발견

그런데 바코드 특성상 숫자들을 검은색과 하얀색으로 구분하여 수십 또는 수백의 라인을 그려주어야 하다 보니 화면이 매번 화면을 다시 그리면 깜박거림에 딜래이까지 생겼습니다.

 

'이걸 메모리에 따로 저장했다가 뿌려줘야 되는 건가?'

하고 있던 중 더블 버퍼링이란걸 알게 되었습니다.

 

 

더블 버퍼링(DoubleBuffer)이란?

GDI+로 그린 그림을 자동으로 메모리에 실어놓고 필요할 때 자동으로 뿌려주는 기능입니다.

물론 그림을 다시 그리면 알아서 업데이트까지 해주죠.

 

문제는 메모리 더 먹는 다는거 ㅎㅎㅎ

 

 

사용하기

윈폼이라면 'InitializeComponent();' 밑에

SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);

이렇게 넣어주시면 됩니다.

 

 

'SetStyle'의 매개변수로 'ControlStyles'타입이 있는데 MSDN에는 이렇게 나와 있습니다.

(참고 : MS Learn - ControlStyles 열거형 )

 멤버 이름  설명
 AllPaintingInWmPaint  true인 경우 해당 컨트롤에서 창 메시지 WM_ERASEBKGND를 무시하여 깜빡임을 줄입니다. 이 스타일은 UserPaint 비트가 true로 설정된 경우에만 적용해야 합니다. 
 CacheText  true인 경우 이 컨트롤에서는 필요할 때마다 Handle에서 텍스트를 가져오지 않고 해당 텍스트의 복사본을 보유합니다. 이 스타일의 기본값은 false입니다. 이 동작으로 성능은 향상되지만 텍스트를 동기화 상태로 유지하기 어렵습니다. 
 ContainerControl  true인 경우 해당 컨트롤은 컨테이너와 유사한 컨트롤입니다. 
 DoubleBuffer  true인 경우 그리기는 버퍼에서 수행되며, 완료된 후에 결과가 화면에 출력됩니다. 이중 버퍼링을 사용하면 컨트롤을 다시 그릴 때 나타나는 깜박임이 없어집니다. DoubleBuffer를 true로 설정하는 경우UserPaintAllPaintingInWmPainttrue로 설정해야 합니다. 
 EnableNotifyMessage  이 스타일이 true로 설정되어 있으면 해당 컨트롤의 WndProc로 보내진 모든 메시지에 대해 OnNotifyMessage 메서드가 호출됩니다. 이 스타일에는 기본적으로 false가 지정됩니다. 부분 신뢰에서는 EnableNotifyMessage가 작동하지 않습니다. 
 FixedHeight  true인 경우 자동으로 크기가 조정될 때 컨트롤은 고정 높이를 갖습니다. 예를 들어, 레이아웃 작업에 의해 새로운 Font를 허용하도록 컨트롤의 크기가 다시 조정될 때 컨트롤의 Height는 변경되지 않은 상태로 유지됩니다. 
 FixedWidth  true인 경우 자동으로 크기가 조정될 때 컨트롤은 고정 너비를 갖습니다. 예를 들어, 레이아웃 작업에 의해 새로운 Font를 허용하도록 컨트롤의 크기가 다시 조정될 때 컨트롤의 Width는 변경되지 않은 상태로 유지됩니다. 
 Opaque  true인 경우 컨트롤을 불투명하게 그리고 배경은 칠하지 않습니다. 
 OptimizedDoubleBuffer  true이면 컨트롤이 화면에 바로 표시되기 전에 우선 버퍼에 놓이게 되어 깜빡임을 줄일 수 있습니다. 이 속성을 true로 설정하는 경우 AllPaintingInWmPainttrue로 설정해야 합니다. 
 ResizeRedraw  true인 경우 크기를 조정할 때 해당 컨트롤을 다시 그립니다. 
 Selectable  true인 경우 해당 컨트롤은 포커스를 받을 수 있습니다
 StandardClick  true인 경우 해당 컨트롤은 표준 Click 동작을 구현합니다. 
 StandardDoubleClick  true인 경우 해당 컨트롤은 표준 DoubleClick 동작을 구현합니다. 이 스타일은 StandardClick 비트가 true로 설정되어 있지 않으면 무시됩니다. 
 SupportsTransparentBackColor  true인 경우, 해당 컨트롤은 255 미만의 알파 구성 요소를 갖는 BackColor를 적용하여 투명도를 시뮬레이션합니다. UserPaint 비트가 true로 설정되어 있고 부모 컨트롤이 Control에서 파생된 경우에만 투명도가 시뮬레이션됩니다.
 UserMouse  true인 경우 해당 컨트롤은 직접 마우스 동작을 처리하며 운영 체제에서 마우스 이벤트를 처리하지 않습니다. 
 UserPaint  true인 경우 운영 체제에서 컨트롤을 그리지 않고 해당 컨트롤이 자기 자신을 그립니다. false인 경우 Paint 이벤트가 발생하지 않습니다. 이 스타일은 Control에서 파생된 클래스에만 적용됩니다. 

 

 

마무리

보통은 깜박임 방지로 많이 사용합니다.

GDI에서 근본적으로 고쳐질 방법은 없는 걸까요?