Форум: "Основная";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];
ВнизTTreeView - скроллер Найти похожие ветки
← →
IgorR (2004-06-09 16:43) [0]Два вопроса по Tree
1. Как сделать скроллер в TreeView типа Flat.
2. Если свойство BevelKind установить bkFlat то при частичном перекрытии скроллеров другим окном скроллеры плохо перерисовываются. Внутри своего приложения можно после вызова дочернего окна вызвать
TreeView1.Perform(CM_RECREATEWND, 0, 0);
но проблеммы возникают и при перекрытии чужими окнами.
Интересно это глюк или фича.
← →
Sha © (2004-06-10 19:44) [1]Эта баго-фича имеется также и в D6 :)
Кроме описанных тобой случаев она проявляется также при максимизации формы, перемещении формы из-за границ экрана, перекрытии формы хинтами и т.п.
Можно попробовать подменить в Controls.pas метод TWinControl.WMNCPaint.
Оригинальный юнит лучше не трогать, достаточно скопировать его в каталог проекта и выполнить билд проекта.
Сделал исправление только сегодня и по-настоящему еще не тестировал.procedure TWinControl.WMNCPaint(var Message: TMessage);
const
InnerStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
OuterStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
EdgeStyles: array[TBevelKind] of Integer = (0, 0, BF_SOFT, BF_FLAT);
Ctl3DStyles: array[Boolean] of Integer = (BF_MONO, 0);
var
DC: HDC;
RC, RW: TRect;
EdgeSize: Integer;
WinStyle: Longint;
begin
inherited;
{ Get window DC that is clipped to the non-client area }
if (BevelKind <> bkNone) or (BorderWidth > 0) then
begin
DC := GetWindowDC(Handle);
try
Windows.GetClientRect(Handle, RC);
GetWindowRect(Handle, RW);
MapWindowPoints(0, Handle, RW, 2);
OffsetRect(RC, -RW.Left, -RW.Top);
{ Draw borders in non-client area }
InflateRect(RC, BorderWidth, BorderWidth);
if BevelKind <> bkNone then
begin
EdgeSize := 0;
if BevelInner <> bvNone then Inc(EdgeSize, BevelWidth);
if BevelOuter <> bvNone then Inc(EdgeSize, BevelWidth);
with RC do
begin
WinStyle := GetWindowLong(Handle, GWL_STYLE);
if beLeft in BevelEdges then Dec(Left, EdgeSize);
if beTop in BevelEdges then Dec(Top, EdgeSize);
if beRight in BevelEdges then Inc(Right, EdgeSize);
if beBottom in BevelEdges then Inc(Bottom, EdgeSize);
if (WinStyle and WS_VSCROLL) <> 0 then Inc(Right, GetSystemMetrics(SM_CXVSCROLL));
if (WinStyle and WS_HSCROLL) <> 0 then Inc(Bottom, GetSystemMetrics(SM_CYHSCROLL));
end;
if BevelWidth > 1 then
begin
RW := RC; RW.Right := RW.Left + EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
RW.Right := RC.Right; RW.Left := RW.Right - EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
RW.Left := RC.Left; RW.Bottom := RW.Top + EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
RW.Bottom := RC.Bottom; RW.Top := RW.Bottom - EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
end;
DrawEdge(DC, RC, InnerStyles[BevelInner] or OuterStyles[BevelOuter],
Byte(BevelEdges) or EdgeStyles[BevelKind] or Ctl3DStyles[Ctl3D] or BF_ADJUST);
end;
finally
ReleaseDC(Handle, DC);
end;
end;
end;
← →
Sha © (2004-06-10 20:33) [2]Надо добавить обработку BorderWidth, метод работает правильно только при BorderWidth=0.
← →
Sha © (2004-06-10 21:14) [3]Так вроде работает. Хотя, может, чего и забыл.
procedure TWinControl.WMNCPaint(var Message: TMessage);
const
InnerStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
OuterStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
EdgeStyles: array[TBevelKind] of Integer = (0, 0, BF_SOFT, BF_FLAT);
Ctl3DStyles: array[Boolean] of Integer = (BF_MONO, 0);
var
DC: HDC;
RC, RW: TRect;
EdgeSize, dx, dy: Integer;
WinStyle: Longint;
begin
inherited;
{ Get window DC that is clipped to the non-client area }
if (BevelKind <> bkNone) or (BorderWidth > 0) then
begin
DC := GetWindowDC(Handle);
try
Windows.GetClientRect(Handle, RC);
GetWindowRect(Handle, RW);
MapWindowPoints(0, Handle, RW, 2);
OffsetRect(RC, -RW.Left, -RW.Top);
{ Draw borders in non-client area }
InflateRect(RC, BorderWidth, BorderWidth);
EdgeSize := 0; dx := 0; dy := 0;
if BevelKind <> bkNone then
begin
if BevelInner <> bvNone then Inc(EdgeSize, BevelWidth);
if BevelOuter <> bvNone then Inc(EdgeSize, BevelWidth);
if beLeft in BevelEdges then Dec(RC.Left, EdgeSize);
if beTop in BevelEdges then Dec(RC.Top, EdgeSize);
if beRight in BevelEdges then Inc(RC.Right, EdgeSize);
if beBottom in BevelEdges then Inc(RC.Bottom, EdgeSize);
end;
WinStyle := GetWindowLong(Handle, GWL_STYLE);
if (WinStyle and WS_VSCROLL) <> 0 then dx:=GetSystemMetrics(SM_CXVSCROLL);
if (WinStyle and WS_HSCROLL) <> 0 then dy:=GetSystemMetrics(SM_CYHSCROLL);
Inc(EdgeSize,BorderWidth);
Inc(RC.Right, dx);
Inc(RC.Bottom, dy);
if (BevelKind <> bkNone) and (BevelWidth > 1) or (BorderWidth > 0) then
begin
RW := RC; RW.Right := RW.Left + EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
RW.Right := RC.Right; RW.Left := RW.Right - EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
RW.Left := RC.Left; RW.Bottom := RW.Top + EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
RW.Bottom := RC.Bottom; RW.Top := RW.Bottom - EdgeSize; Windows.FillRect(DC, RW, Brush.Handle);
end;
if (dx <> 0) and (dy <> 0) then
begin
RW.Bottom := RC.Bottom - EdgeSize; RW.Top := RW.Bottom - dy;
RW.Right := RC.Right - EdgeSize; RW.Left := RW.Right - dx;
Windows.FillRect(DC, RW, Brush.Handle);
end;
if BevelKind <> bkNone then
begin
DrawEdge(DC, RC, InnerStyles[BevelInner] or OuterStyles[BevelOuter],
Byte(BevelEdges) or EdgeStyles[BevelKind] or Ctl3DStyles[Ctl3D] or BF_ADJUST);
end;
finally
ReleaseDC(Handle, DC);
end;
end;
end;
← →
Sha © (2004-06-11 12:49) [4]Еще одна правка:
добавить объявлениеvar SaveColor: TColor;
послеDC := GetWindowDC(Handle);
добавитьSaveColor := Brush.Color; Brush.Color := clBtnFace;
послеReleaseDC(Handle, DC);
добавитьBrush.Color := SaveColor;
В заключение замечу, что мы по примеру Borland"а рисуем скаты Bevel"а для TWinControl"а всегда толщиной в одну линию, причем Border рисуем не между скатами Bevel"а, в между Bevel"ом и клиентской областью. Почему так - загадка. В глаза это не бросается, т.к. обычно BevelWidth=1, BorderWidth=0 и почти всегда BevelWidth<=1, BorderWidth<=1.
Конечно, это можно подправить и рисовать TWinControl аналогично TCustomPanel.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.06.27;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.035 c