2017-09-19 12 views
0

아래 코드를 사용하여 Windows ListView 헤더 컨트롤을 하위 클래스로 만듭니다. 내 절차는 정상적으로 작동하며 헤더 컨트롤 위로 마우스를 가져 가면 올바르게 응답합니다.Ownerdrawn Listview Header Line을 바로 표시하는 방법

내 문제를 내가 "처음으로"큰 목록을 만들 때,리스트까지 표시되지 않습니다 헤더 라인이 완전히 채워이다 : 나는 열린 목록을 삭제하면,

Header line during loading big list 1st time

다음 하고 새, 심지어 같은 이전을 작성, 헤더 행은 목록이 완료 될 때까지 기다리지 않고 즉시 보여줍니다

Header line during loading big list 2nd time

내가 헤더 컨트롤을 서브 클래 싱하지 않는 경우, 기본 W indows 프로 시저는 항상 목록이 완료 될 때까지 기다리지 않고 즉시 헤더 행을 표시하지만 사용자 정의는 손실됩니다.

헤더 줄을 즉시 표시하려면 무엇을 놓치고 있습니까?

참고 :

내가 시작하기 전에 및 추가 목록보기 항목을 마친 후 LockWindowUpdate()를 호출합니다. 나는 LockWindowUpdate()이라고하지 않으려 고했지만 그 결과는 모든 항목을 추가 한 후에도 헤더 행이 표시되지 않는다는 것을 나타내므로 헤더 행 위로 마우스를 이동하여 새로운 WM_PAINT 메시지를 보낼 때까지 기다립니다.

가 여기 내 서브 클래스 함수이다 :

static char* HeaderText[20] = {"A","B","C","D","E","F","G","H","I","J", 
           "K","L","M","N","O","P","Q","R","S","T"} ; 


LRESULT APIENTRY HeaderSubclassProc (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)       
{ 
static int  y ; 
static int  xe ; 
static int  xr ; 
static int  HBtn = -1 ; 
static RECT Hrc ; 
static HPEN Pen ; 
static HPEN HPen ; 
static HBRUSH Brush ; 
static HBRUSH HBrush ; 
static TRACKMOUSEEVENT tme = {sizeof (TRACKMOUSEEVENT),TME_LEAVE,NULL, 
           HOVER_DEFAULT} ; 
HDC  hDC ; 

switch (msg) { 
    RECT rc ; 

    case IDM_INIT : 
     Pen = CreatePen (PS_SOLID,0,0xF2F2F2) ; 
     HPen = CreatePen (PS_SOLID,0,0xF88420) ; 
     Brush = CreateSolidBrush (0xD2D2D2) ; 
     HBrush = CreateSolidBrush (0xFFEFE0) ; 
     Header_GetItemRect (hwnd,19,&rc) ; 
     xr = rc.right ; 
     tme.hwndTrack = hwnd ; 
     return 0 ; 

    case WM_CLOSE : 
     DeleteObject (Pen) ; 
     DeleteObject (HPen) ; 
     DeleteObject (Brush) ; 
     DeleteObject (HBrush) ; 
     return 0 ; 

    case WM_SIZE : 
     TEXTMETRIC tm ; 
     hDC = GetDC (hwnd) ; 
     GetTextMetrics (hDC,&tm) ; 
     ReleaseDC (hwnd,hDC) ; 
     Header_GetItemRect (hwnd,0,&rc) ; 
     y = (rc.bottom - rc.top - tm.tmHeight)/2 + tm.tmAscent ; 
     xe = LOWORD (lParam) ; 
     break ; 

    case WM_MOUSELEAVE : 
     HBtn = -1 ; 
     InvalidateRect (hwnd,&Hrc,true) ; 
     return 0 ; 

    case WM_MOUSEMOVE : 
     int x ; 
     x = LOWORD (lParam) ; 
     if (HBtn > -1 && x > xr) { 
      HBtn = -1 ; 
      InvalidateRect (hwnd,&Hrc,true) ; 
      break ; 
     } /* if (HLBtn == 19 && x > xr) */ 
     for (int Btn = 0 ; Btn < 20 ; Btn++) { 
      Header_GetItemRect (hwnd,Btn,&rc) ; 
      if (x > rc.left && x < rc.right) { 
       if (Btn == HBtn) 
        break ; 
       HBtn = Btn ; 
       Hrc = rc ; 
       InvalidateRect (hwnd,NULL,true) ; 
       break ; 
      } /* if (x > rc.left && x < rc.right) */ 
     } /* for (int Btn = 0 ; Btn < 20 ; Btn++) */ 
     TrackMouseEvent (&tme) ; 
     break ; 

    case WM_PAINT : 
     PAINTSTRUCT ps ; 
     hDC = BeginPaint (hwnd,&ps) ; 
     int DefDC = SaveDC (hDC) ; 

     SelectObject (hDC,Pen) ; 
     SelectObject (hDC,Brush) ; 
     SetTextAlign (hDC,TA_BASELINE | TA_CENTER) ; 
     SetBkMode (hDC,TRANSPARENT) ; 

     for (int Btn = 0 ; Btn < 20 ; Btn++) { 
      if (Btn == HBtn) 
       continue ; 
      Header_GetItemRect (hwnd,Btn,&rc) ; 
      int x = (rc.right + rc.left)/2 ; 
      Rectangle (hDC,rc.left,rc.top,rc.right + 1,rc.bottom) ; 
      ExtTextOut (hDC,x,y,ETO_NUMERICSLATIN,&rc,HeaderText[Btn], 
          (UINT) strlen (HeaderText[Btn]),NULL) ; 
     } /* for (int Btn = 0 ; Btn < 20 ; Btn++) */ 
     Rectangle (hDC,rc.right,rc.top,xe,rc.bottom) ; 

     if (HBtn > -1) { 
      Header_GetItemRect (hwnd,HBtn,&rc) ; 
      x = (rc.right + rc.left)/2 ; 
      SelectObject (hDC,HPen) ; 
      SelectObject (hDC,HBrush) ; 
      Rectangle (hDC,rc.left + 1,rc.top + 1,rc.right,rc.bottom - 1) ; 
      ExtTextOut (hDC,x,y,ETO_NUMERICSLATIN,&rc,HeaderText[HBtn], 
          (UINT) strlen (HeaderText[HBtn]),NULL) ; 
     } /* if (HLBtn > -1) */ 

     RestoreDC (hDC,DefDC) ; 
     EndPaint (hwnd,&ps) ; 
     return 0 ; 

} /* switch (msg) */ 

return CallWindowProc ((WNDPROC) DefaultHeaderProc,hwnd,msg,wParam,lParam) ; 

} /* HeaderSubclassProc */ 
+0

어쩌면 목록을 어떻게 든 무효화해야합니까? – VuVirt

답변

2

당신은 확실히 전혀 LockWindowUpdate()를 사용해서는 안된다 (설명 Raymond Chen's blog 이유에 수많은 기사가있다).

올바른 해결책은 당신이 당신의 업데이트를 완료 할 때까지 그 도면을 비활성화 도면을 다시 활성화, 그리고 마지막으로 InvalidateRect()/UpdateWindow(), 또는 RedrawWindow()로 다시 그리기를 트리거 다시 WM_SETREDRAW를 보낼 수있는 ListView에게 WM_SETREDRAW 메시지를 보내는 것입니다.

또는 use the ListView in virtual mode 특히 많은 항목을 표시하려는 경우.

+0

WM_SETREDRAW를 시도했지만 문제가 해결되지 않았습니다. 다시 네이티브 Windows 헤더 프로 시저에서 작동하지만 서브 클래 싱 된 헤더에서는 작동하지 않습니다. 목록을 마친 후에 프로그래밍 방식으로 머리글을 다시 그릴 수 없으므로 문제가 더욱 악화됩니다. InvalidateRect()/UpdateWindow() 및 RedrawWindow()가 헤더를 표시하지 못했습니다. 머리글을 표시하려면 수동으로 커버/커버를 풀어야합니다. WM_PAINT의 하위 클래스 처리에서 뭔가가없는 것 같지만 알아낼 수는 없습니다. – makhlouf

+0

ListView 헤더를 서브 클래 싱하는 방법이나 ListView 항목을 채우는 방법을 표시하지 않았습니다. –