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