Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
3-1085827809
KADAN
2004-05-29 14:50
2004.06.27
last insert id в MSSQL


1-1086946538
Litr
2004-06-11 13:35
2004.06.27
QuckRep


4-1084868096
Vadim X
2004-05-18 12:14
2004.06.27
Как получить время с GMT?


1-1086790419
TUser
2004-06-09 18:13
2004.06.27
Invalid parameter


14-1086702048
Weber
2004-06-08 17:40
2004.06.27
Копировать с CD на CD





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский