meine frage jetzt, wie (und wo im code) bringe ich die listbox dazu sich komplett neu zu zeichnen!
wenn einzelne Items neu gezeichnet werden, updatet die defaultwinproc nur die umgebenden items, da sich aber durch die größenänderung im sichtbaren bereich der listbox ALLES verschiebt, bleiben unschöne artefakte. wie verhindere ich das?
mache ich das neuzeichnen während WM_DRAWITEMS kann man sich vorstellen wie es flackert ... da bringt man Delphi schonmal zum Absturz
Danke im Voraus, Assa
hier mal die wichtigen stellen der winproc.
<pre>
WM_PAINT:
begin
BeginPaint(hwnd, ps);
SetTextColor(ps.hdc, GetSysColor(COLOR_GRAYTEXT));
GetTextMetrics(ps.hdc, tm);
GetWindowRect(GetDlgItem(hwnd, IDC_HEADER), rect);
ScreenToClient(hwnd, rect.TopLeft);
ScreenToClient(hwnd, rect.BottomRight);
y := (rect.BottomRight.y + rect.TopLeft.y - tm.tmHeight) div 2;
setbkmode(ps.hdc, TRANSPARENT);
//textout()
EndPaint(hwnd, ps);
end;
WM_DRAWITEM:
if UINT(wParam) = IDC_LIST1 then begin
if PDRAWITEMSTRUCT(lParam).itemID <> Cardinal(-1) then begin
case PDRAWITEMSTRUCT(lParam).itemAction of
ODA_SELECT,
ODA_DRAWENTIRE:
begin
p1.lbStyle := BS_SOLID;
p1.lbColor := RGB($FF, 0, 0);
redbr := CreateBrushIndirect(p1);
case (PDrawItemStruct(lParam).itemState and ODS_SELECTED = ODS_SELECTED) of
true: begin
Sendmessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_SE TITEMHEIGHT,PDRAWITEMSTRUCT(lParam).ItemID,y_offse t);
SendMessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_GE TITEMRECT,PDRAWITEMSTRUCT(lParam).ItemID,integer(@ PDRAWITEMSTRUCT(lParam).rcItem));
fillrect(PDRAWITEMSTRUCT(lParam).hDC, PDRAWITEMSTRUCT(lParam).rcItem, redbr);
SetBkColor(PDRAWITEMSTRUCT(lParam).hDC, RGB($FF, 0, 0));
settextcolor(PDRAWITEMSTRUCT(lParam).hDC, $0);
end;
false: begin
Sendmessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_SE TITEMHEIGHT,PDRAWITEMSTRUCT(lParam).ItemID,y_offse t div 2);
SendMessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_GE TITEMRECT,PDRAWITEMSTRUCT(lParam).ItemID,integer(@ PDRAWITEMSTRUCT(lParam).rcItem));
fillrect(PDRAWITEMSTRUCT(lParam).hDC, PDRAWITEMSTRUCT(lParam).rcItem, GetStockObject(BLACK_BRUSH));
SetBkColor(PDRAWITEMSTRUCT(lParam).hDC, $0);
settextcolor(PDRAWITEMSTRUCT(lParam).hDC, RGB($FF, 0, 0));
end;
end;
GetTextMetrics(PDRAWITEMSTRUCT(lParam).hDC, tm);
y := (PDRAWITEMSTRUCT(lParam).rcItem.bottom + PDRAWITEMSTRUCT(lParam).rcItem.top - tm.tmHeight) div 2;
recnum := Sendmessage(PDRAWITEMSTRUCT(lParam).hwndItem, LB_GETITEMDATA, PDRAWITEMSTRUCT(lParam).ItemID, 0);
//text
case (PDrawItemStruct(lParam).itemState and ODS_SELECTED = ODS_SELECTED) of
TRUE: begin
//text
DrawFocusRect(PDRAWITEMSTRUCT(lParam).hDC, PDRAWITEMSTRUCT(lParam).rcItem);
DeleteObject(redbr);
end;
end;
end;
end;
end;
result := TRUE;
end else result := false;</pre>
wenn einzelne Items neu gezeichnet werden, updatet die defaultwinproc nur die umgebenden items, da sich aber durch die größenänderung im sichtbaren bereich der listbox ALLES verschiebt, bleiben unschöne artefakte. wie verhindere ich das?
mache ich das neuzeichnen während WM_DRAWITEMS kann man sich vorstellen wie es flackert ... da bringt man Delphi schonmal zum Absturz
Danke im Voraus, Assa
hier mal die wichtigen stellen der winproc.
<pre>
WM_PAINT:
begin
BeginPaint(hwnd, ps);
SetTextColor(ps.hdc, GetSysColor(COLOR_GRAYTEXT));
GetTextMetrics(ps.hdc, tm);
GetWindowRect(GetDlgItem(hwnd, IDC_HEADER), rect);
ScreenToClient(hwnd, rect.TopLeft);
ScreenToClient(hwnd, rect.BottomRight);
y := (rect.BottomRight.y + rect.TopLeft.y - tm.tmHeight) div 2;
setbkmode(ps.hdc, TRANSPARENT);
//textout()
EndPaint(hwnd, ps);
end;
WM_DRAWITEM:
if UINT(wParam) = IDC_LIST1 then begin
if PDRAWITEMSTRUCT(lParam).itemID <> Cardinal(-1) then begin
case PDRAWITEMSTRUCT(lParam).itemAction of
ODA_SELECT,
ODA_DRAWENTIRE:
begin
p1.lbStyle := BS_SOLID;
p1.lbColor := RGB($FF, 0, 0);
redbr := CreateBrushIndirect(p1);
case (PDrawItemStruct(lParam).itemState and ODS_SELECTED = ODS_SELECTED) of
true: begin
Sendmessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_SE TITEMHEIGHT,PDRAWITEMSTRUCT(lParam).ItemID,y_offse t);
SendMessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_GE TITEMRECT,PDRAWITEMSTRUCT(lParam).ItemID,integer(@ PDRAWITEMSTRUCT(lParam).rcItem));
fillrect(PDRAWITEMSTRUCT(lParam).hDC, PDRAWITEMSTRUCT(lParam).rcItem, redbr);
SetBkColor(PDRAWITEMSTRUCT(lParam).hDC, RGB($FF, 0, 0));
settextcolor(PDRAWITEMSTRUCT(lParam).hDC, $0);
end;
false: begin
Sendmessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_SE TITEMHEIGHT,PDRAWITEMSTRUCT(lParam).ItemID,y_offse t div 2);
SendMessage(PDRAWITEMSTRUCT(lParam).hwndItem,LB_GE TITEMRECT,PDRAWITEMSTRUCT(lParam).ItemID,integer(@ PDRAWITEMSTRUCT(lParam).rcItem));
fillrect(PDRAWITEMSTRUCT(lParam).hDC, PDRAWITEMSTRUCT(lParam).rcItem, GetStockObject(BLACK_BRUSH));
SetBkColor(PDRAWITEMSTRUCT(lParam).hDC, $0);
settextcolor(PDRAWITEMSTRUCT(lParam).hDC, RGB($FF, 0, 0));
end;
end;
GetTextMetrics(PDRAWITEMSTRUCT(lParam).hDC, tm);
y := (PDRAWITEMSTRUCT(lParam).rcItem.bottom + PDRAWITEMSTRUCT(lParam).rcItem.top - tm.tmHeight) div 2;
recnum := Sendmessage(PDRAWITEMSTRUCT(lParam).hwndItem, LB_GETITEMDATA, PDRAWITEMSTRUCT(lParam).ItemID, 0);
//text
case (PDrawItemStruct(lParam).itemState and ODS_SELECTED = ODS_SELECTED) of
TRUE: begin
//text
DrawFocusRect(PDRAWITEMSTRUCT(lParam).hDC, PDRAWITEMSTRUCT(lParam).rcItem);
DeleteObject(redbr);
end;
end;
end;
end;
end;
result := TRUE;
end else result := false;</pre>
Comment