본문 바로가기

유물/SodExplorer band

IShellView 페인팅 문제

Sod Explorer 에서는 보이지 않던 문제가 발생했다.
페인팅 문제

일부분만 그려진 모습


탐색기창이 맨 처음 보여진 후, 숨겼다가 다시 보여질 때 포커스가 리스트뷰(파일뷰)에 있다면 스샷과 같은 현상이 나타난다. 키보드 포커스를 가지고 있기 때문에 커서키로 움직이면 관련영역들이 그려지기 시작한다. 포커스가 트리뷰에 있는 상태로 보여지게되면 이런 현상은 없다.

::ShowWindow(, SW_SHOW) 후에 ::InvalidateRect()를 호출 해 일단 해결해 놨지만, 왜 그런지 이유가 궁금하다.
찝찝한 이 기분.


업데이트: 2010/03/04

InvalidateRect() 호출로 파일뷰가(리스트뷰 컨트롤) 완벽하게 다시 그려지지 않았다.

스샷에서 파일뷰부분에 스크롤바가 안보이는 것을 확인 할 수 있다. 게다가 위쪽 빨간 박스부분에서 트리뷰와 리스트뷰를 비교해보면 리스트뷰의 클라이언트 엣지부분에 스타일이(성큰인가?) 적용되지 않은 것도 확인할 수 있다. 아마도 클라이언트부분만 다시 그려진 듯 하다.

아무튼 ::InvalidateRect() 대신 ::RedrawWindow()를 호출해줌으로서 해결했다.
// defView는 리스트뷰의 부모 핸들, 이 코드에선 SHELLDLL_DefView 클래스 윈도우의 핸들이다.
::RedrawWindow(defView, 0, 0, RDW_INVALIDATE|RDW_ALLCHILDREN);
리스트뷰가 아니라, 리스트뷰의 부모핸들[각주:1]이고 플래그로 RDW_ALLCHILDREN를 줘 모든 자식윈도우를 다시 그려주면 파일뷰가 제대로 보여지게 된다. 위에도 적었지만 이게 참 웃기게도 포커스를 가지고 있을 때 생기는 문제인데, WinAPI에 대해서 더 공부가 필요한듯 하다. API로 한답시고 삽질 중인데, MFC로 했으면 어땟을까 하는 생각도 든다(물론 MFC로 잘 하는건 아니다). ㅜㅜ
  1. IShellFolder::CreateViewObject로 얻은 IShellView 객체는 SHELLDLL_DefView 클래스를 가지는 윈도우이고 자식윈도우가 리스트뷰 컨트롤이다. 실제 윈도 탐색기의 경우는 SHELLDLL_DefView의 자식윈도우로 몇단계를 더 내려가 그 마지막 자식윈도우로서 리스트뷰 컨트롤이 위치한다. [본문으로]