如何立即显示Ownerdrawn Listview标题行

如何立即显示Ownerdrawn Listview标题行,listview,winapi,header,ownerdrawn,Listview,Winapi,Header,Ownerdrawn,我使用下面的代码对Windows ListView头控件进行子类化。我的程序运行良好,对鼠标悬停在标题控件上的响应良好 我的问题是,当我“第一次”创建一个大列表时,在完全填充列表之前,标题行不会显示: 然后,如果我删除打开的列表并创建一个新列表,甚至是相同的旧列表,标题行将立即显示,而不是等待列表完成: 如果我没有对header控件进行子类化,则本机Windows过程总是立即显示标题行,而不是等待列表完成,但这样我就失去了自定义 有什么建议我错过了让标题行立即显示 注: 在开始添加列表视图项

我使用下面的代码对Windows ListView头控件进行子类化。我的程序运行良好,对鼠标悬停在标题控件上的响应良好

我的问题是,当我“第一次”创建一个大列表时,在完全填充列表之前,标题行不会显示:

然后,如果我删除打开的列表并创建一个新列表,甚至是相同的旧列表,标题行将立即显示,而不是等待列表完成:

如果我没有对header控件进行子类化,则本机Windows过程总是立即显示标题行,而不是等待列表完成,但这样我就失去了自定义

有什么建议我错过了让标题行立即显示

注:

在开始添加列表视图项之前和完成添加列表视图项之后,我调用
LockWindowUpdate()。我试图不调用
LockWindowUpdate()
,但结果是,即使在添加完所有项目后,标题行也不会显示,它会等待,直到我将鼠标移到标题行上,强制生成一个新的
WM_PAINT
msg

下面是我的子类函数:

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 */
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)
{
静态智力;
静态int-xe;
静态int-xr;
静态int HBtn=-1;
静态直读Hrc;
静电笔;
静态HPEN-HPEN;
静电刷;
静态HBRUSH-HBRUSH;
静态TRACKMOUSEEVENT tme={sizeof(TRACKMOUSEEVENT),tme_LEAVE,NULL,
悬停_DEFAULT};
HDC-HDC;
开关(msg){
RECT-rc;
案例IDM_INIT:
Pen=CreatePen(PS_实心,0,0xF2F2);
HPen=CreatePen(PS_实体,0,0xF88420);
笔刷=CreateSolidBrush(0xD2D2D2D2);
HBrush=CreateSolidBrush(0xFFEFE0);
标题_GetItemRect(hwnd、19和rc);
xr=rc.right;
tme.hwndTrack=hwnd;
返回0;
案例WM_结束:
删除对象(笔);
删除对象(HPen);
删除对象(画笔);
删除对象(HBrush);
返回0;
案例WM_大小:
textmetricTM;
hDC=GetDC(hwnd);
GetTextMetrics(hDC和tm);
释放DC(hwnd、hDC);
标头_GetItemRect(hwnd、0和rc);
y=(rc.bottom-rc.top-tm.tmHeight)/2+tm.tmastence;
xe=低ORD(LPRAM);
打破
案例WM_MOUSELEAVE:
HBtn=-1;
无效(hwnd和Hrc,正确);
返回0;
案例WM_MOUSEMOVE:
int x;
x=低ORD(lParam);
如果(HBtn>-1&&x>xr){
HBtn=-1;
无效(hwnd和Hrc,正确);
打破
}/*如果(HLBtn==19&&x>xr)*/
对于(int Btn=0;Btn<20;Btn++){
标题_GetItemRect(hwnd、Btn和rc);
如果(x>rc.left&&xrc.left&&x-1){
标题_GetItemRect(hwnd、HBtn和rc);
x=(右钢筋混凝土+左钢筋混凝土)/2;
选择对象(hDC、HPen);
选择对象(hDC、HBrush);
矩形(hDC,rc.left+1,rc.top+1,rc.right,rc.bottom-1);
ExtTextOut(hDC、x、y、ETO_数字拉丁语和rc、HeaderText[HBtn],
(UINT)strlen(HeaderText[HBtn]),空;
}/*如果(HLBtn>-1)*/
恢复的数据中心(hDC、DefDC);
端漆(hwnd和ps);
返回0;
}/*开关(msg)*/
返回CallWindowProc((WNDPROC)DefaultHeaderProc、hwnd、msg、wParam、lParam);
}/*HeaderSubclassProc*/

您绝对不应该使用
LockWindowUpdate()
(有很多文章解释了原因)

正确的解决方案是向ListView发送一条消息以禁用其绘图,直到您完成更新,然后再次发送
WM_SETREDRAW
以重新启用绘图,最后触发使用/或重新绘制


或者,特别是当您要显示大量项目时。

您绝对不应该使用
LockWindowUpdate()
(有许多文章解释了原因)

正确的解决方案是向ListView发送一条消息以禁用其绘图,直到您完成更新,然后再次发送
WM_SETREDRAW
以重新启用绘图,最后触发使用/或重新绘制


或者,特别是当您要显示很多项目时。

也许您需要以某种方式使列表无效?也许您需要以某种方式使列表无效?我尝试了WM_SETREDRAW,但它无法解决问题。它同样适用于本机Windows标头过程,但