Delphi VCL TStatusBar의 Owner Draw 렌더링 문제 해결

Delphi의 VCL 컨트롤 중에서 TStatusBar 컨트롤이 있습니다. 이 컨트롤은 대부분의 경우 정상적으로 원하는대로 Owner Draw를 구현하여 사용할 수 있지만 뜻하지 않게 일부 운영 체제에서는 Owner Draw가 회피당하거나 (Windows 2000), Owner Draw에 대한 처리가 정확히 마무리되지 않아서 잔상이 남는 버그 (Windows XP, Windows Server 2003)가 발생하곤 합니다. 이 문제를 해결하기 위한 두 가지 방법을 소개하고자 합니다. 참고로 이 버그는 Windows NT 4.0 + Delphi 5.0 환경에서도 발견이 되었으며 이에 그치지 않고 Delphi 2007 + Windows 2000/XP/Server 2003에서도 여전히 나타나는 버그로 보입니다.

Solution 1: 제일 손쉬운 방법은 TStatusBar 컨트롤의 부모를 TForm이 아닌 TPanel로 하여 TPanel을 대신 TForm에 올려놓는 방법입니다. 이렇게 하면 고질적인 Owner Draw 렌더링 버그를 원천적으로 해결하고 멤버 변수 선언에도 영향을 주지 않으므로 리팩터링이 필요하지 않습니다.

Solution 2: 이미 디자인타임에서 컨트롤을 많이 사용하였고 마우스로 조작하기 까다로운 UI를 가진 창에서 문제가 발생한다면 – 또는 – 프로그래밍 방식으로 문제를 해결할 필요가 있다면 다음의 지침에 따라 WndProc 메서드를 추가 구현합니다.


Procedure TForm1.WndProc(var Message: TMessage);
Begin
   Case Message.Msg Of
      { 이런저런 메시지 처리 코드가 포함될 것입니다. 생략합니다. }
      WM_DRAWITEM:
      Begin
         If (Message.WParam) <> 0 And (Message.LParam) <> 0 Then
         Begin
            With PDrawItemStruct(Message.LParam)^ Do
            Begin
               If ctlType = ODT_TYPE Then
                  ctlType := 0;
            End;
         End;
      End;
   End;
   { 상위 윈도 메시지 처리기를 호출하지 않으면 문제가 발생하므로 꼭 확인합니다. }
   Inherited WndProc(Message);
End;

굵게 표시한 코드가 문제를 해결하는데 필요한 코드와 잊지 말아야 할 코드들입니다. 만약 WndProc 메서드를 처음 오버라이드하는 경우 상위 메시지 처리기 호출을 놓치기 쉽습니다. 폼을 생성하지 못하고 에러 메시지만 나온 후 프로그램이 바로 종료되어버린다면 반드시 WndProc 메서드가 상위 메시지 처리기를 올바르게 호출하고 있는지 점검해야 하겠습니다.

도움이 되셨기를 바랍니다. 🙂

자료 출처: http://buglist.jrsoftware.org/generated/entry0624.htm

댓글 남기기