![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Пропадает полоса прокрутки Dbgrid [D7, Paradox]
AntonUSAnoV © (2008-01-08 18:22:00)Уважаемые программисты хоть я уже задавал этот вопрос, ответа на него даже коллективным путём мы не нашли, в связи с этим я хотел бы вновь его поднять:
Суть такова: пользователь производит SQL выборку из БД, затем нажимает кнопку все записи, которая устанавливает datasource-dataset в исходное положение, т.е. показывает все записи. И тут в dbgrid у меня почему то пропадает полоса прокрутки(вертикальная), причём пропадает, только если после выборки результат - 1 запись, а если их несколько то соответственно не пропадает.
Наблюдение: после выборки-1 запись - полоса прокрутки тут же пропадает, и при нажатии на кнопку все записи не появляется, а если после выборки- несколько записей, полоса прокрутки не пропадает.
В ходе предыдущих раздумий пришёл к выводу что это проблема отображения DBgrida в виндоус ХП и виста, и связана она со стилями Виндоус, как решить никто не знает, вопрос уже обсуждался на этой ветке под этой же темой
sniknik (2008-02-06 08:33:00) [1]> думал обойтись inherited плюс дописать включение скролла.
процедура не виртуальная...
> не хотел переписывать всю процедуру
как ни печально но этим не обойдешься, надо править генофонд... или переписывать очень многое (куча вызовов из разных мест). решение с в включением модуля в проект, и правкой 1 строчки, имхо, оптимальное.
> то у грида ScrollBars = ssVertical
ну так... я же писал что он не убирается а "прячется". причем не дельфевским кодом, а "у нутре" при определенных условиях. то что дельфевское свойство осталось неизмененным это как бы само собой.
> и второй зависит от первого, в гриде для второго датасета глюка никогда не бывает.
тогда там установка позиции вызывается еще раз, с теми же параметрами т.е. винда пытается спрятать еще раз, ошибка накапливается, чтото там становится больше допустимого и переинициализируется (иначе бы оно не восстанавливалось в твоем первом тесте, просто после первого раза пропал бы скрол и все), я же именно изза этого начал думать, что там сравнение с ширины с константой не больше суммы реальных длинн, а у реальной на 1 пиксель больше... второе же добавление 16ти всяко больше одной реальной 17-ти вот и восстанавливает. правда потом отказался от подобного вывода тк. установка ширины скрола на манер "без схем" ничего не поменяла.
проверь, сделай в первом после открытия с 0-ем записей не "hide" скролу как предлагал проверить в [28], а еще вызов UpdateScrollBar (или кода из него) и глюк тоже "уйдет". (теоретически. не проверял) это, если подтвердится, гарантированно покажет что в связанных есть второй вызов.
Prohodil Mimo (2008-02-06 00:14:00) [2]Пытался написать наследника DBGrid-а и в нём применить [29], но пока не получилось, т.к. не хотел переписывать всю процедуру, думал обойтись inherited плюс дописать включение скролла. Попозже попробую переписать процедуру полностью.
Нашёл, что когда виден глюк в 1 пиксель, то у грида ScrollBars = ssVertical. Пройдясь по модулям Grids и DBGrids не нашёл, где он вообще меняет значение. Но если в UpdateScrollBar приписать ScrollBars := ssVertical, то скролл рисуется всегда, правда по много раз и при этом мигает.
Ещё что заметил: если на форме два датасета, и второй зависит от первого, в гриде для второго датасета глюка никогда не бывает.
Проверял на FIBPlus.
sniknik (2008-02-05 13:34:00) [3]> - мусора нет - проблема убрана...
ага. приезжаешь в автосервис говоришь
- "чегото движок стал плохо тянуть, и бензина жрать больше..."
- "так посмотрим... ба, да у вас стук какойто из двигателя, клапана стучат, видать разрегулированные... движок перебирать нужно"
- "что?! какой перебор? проблема говорите в стуке? да обложите двигатель шумоизолятором (поролоном) его слышно и не будет..."
но шум, это не поломка, это признак (!!!).
вообще не понимаю, все же легко (после начала серьезного разговора с Prohodil Mimo © (02.02.08 00:42) [24]) можно проверить.
ты проверил?...
получил глюк, после поставил у грида (одного из) BorderStyle = bsNone, и в нем глюк прекратился?
я так думаю нет, т.к. проверял много всего и это в том числе, и решеним это не является (мое решение уже показано, и оно работает).
я так думаю ты просто решил вернуть стиль балагана ветке, такой который был до [24]...
han_malign (2008-02-05 12:39:00) [4]
> этим ты только уберешь видимую часть общего (не проблему! ), проблема не в том, что эта часть видна/не видна
- мусора нет - проблема убрана...
Где-то в недрах GUI неправильно вычисляется регион обновления полос прокрутки при увеличеном нижнем/правом(LeftToRigh) размере неклиентской части(и в случае WS_EX_CLIENTEDGE, и - WM_NCCALCSIZE). Это хорошо видно если поверх другое окно потаскать. На вскидку - не обновляется часть выходящая внутрь за рамки "обычной" полосы прокрутки, квадрат в углу между двумя полосами прокрутки по жизни не отрисовывается(в некоторых случаях лечится в WM_NCPAINT)
А если еще и BevelKind <> bkNone и/или BorderWidth > 0, то в TWinControl.WMNCPaint вся неклиентская часть закрашивается, и полосы прокрутки в некоторых случаях вообще пропадают(до изменения позиции/диапазона)...
sniknik (2008-02-05 10:27:00) [5]han_malign © (05.02.08 08:55) [31]
>> видна её часть шириной в 1 пиксель, как будто не всё затёрлось
> BorderStyle:= bsNone;
этим ты только уберешь видимую часть общего (не проблему!), проблема не в том, что эта часть видна/не видна, это просто показатель по которому можно судить как/что делает винда, то, по чему можно предположить в отсутствии исходников.
han_malign (2008-02-05 08:55:00) [6]
> видна её часть шириной в 1 пиксель, как будто не всё затёрлось
BorderStyle:= bsNone;
sniknik (2008-02-03 10:41:00) [7]нет, с константой "облом", при установке в схеме у винды ширины скрола - 16, ничего не меняется. значит всетаки поведение различается (попытка ускорить рючечки? ;о))
sniknik (2008-02-03 10:36:00) [8]чегото я так подумал подумал... и надумал, что грид не виноват, только винда. все правильно там грид высчитывает, это сама винда почему то решает "прятать" полосу вместо ее удаления (может когда без схем, она делает также, но тогда у нее глюк в другом, гдето ширина скрола 16 забита константой, поэтому сама размер рабочей области определяет неправильный, а во второй раз когда вторая добавка 16-и всетаки перекрывает общую ширину идет перерасчет, при существующем горизонтальном скроле перерасчет идет уже сним в любом случае и получается ошибка маскируется).
ну, в винду не влезешь, поэтому самым простым выходом будет наверное удалять полосу явно, после, при достижении условий когда она прячется (на работу без схем повлиять не должно).
опять же делаем подключение уже DBGrids к проекту и добавляем строчки
procedure TCustomDBGrid.UpdateScrollBar;
....
else SINew.nPos := 2;
end;
if (SINew.nMin <> SIOld.nMin) or (SINew.nMax <> SIOld.nMax) or
(SINew.nPage <> SIOld.nPage) or (SINew.nPos <> SIOld.nPos) then begin
SetScrollInfo(Self.Handle, SB_VERT, SINew, True);
if SINew.nMax <= 1 then
ShowScrollBar(Self.Handle, SB_VERT, false);
end;
end;
end;
sniknik (2008-02-03 02:34:00) [9]> А вот кто виноват, грид или датасет - вопрос.
не датасет точно, у него все понятно, винда похоже (как понял), она при установке позиции скрола в соответствии номером записи (SetScrollPos) при схемах, стала скрывать полосу при значении -1, но не удаляет ее, грид же "не зная" что скрол спрятан оставляет клиентскую область как есть, и при пере создании(/пере инициализации?) окна (я еще не дошел до него, но чтото там наверняка есть... ;)), указывает эту область к которой добавляется ширина скрола, почемуто 16, как без схем, а реально полоса со схемами 17 (GetSystemMetrics(SM_CXVSCROLL)) вот он на один пиксель и "вылезает" который ты и видел.
а при пустом при 0 записей там обрамляющая рамка не видна со стороны скрола, обрати внимание. т.е. уже при 0 скрол "сломан". если же при пустом (0 записей) сделать "hide" скролу (см. ниже), то рамка появится, и последующее "безобразие" тоже не настанет...
это так, прикидка, но вроде похоже... потом еще "поковыряюсь" если будет желание.
> А можно ли грид научить не прятать полосу прокрутки, независимо от кол-ва записей?
попробуй.
сразу после открытия, датасета.
ShowScrollBar(DBGrid1.Handle, SB_VERT, false); //это для выключения "порченной" полосы (та что в пиксель)
ShowScrollBar(DBGrid1.Handle, SB_VERT, true); //показать
или скопируй и подключи модуль Grids к проекту (чтобы генофонд не править) и добавь там строчку в процедуру
procedure TCustomGrid.UpdateScrollRange;
....
end;
{????}
ShowScrollBar(Handle, SB_VERT, true);
{????}
finally
FScrollBars := OldScrollBars;
end;
UpdateScrollPos;
if (FTopLeft.X <> OldTopLeft.X) or (FTopLeft.Y <> OldTopLeft.Y) then
TopLeftMoved(OldTopLeft);
end;
это еще до обновления скрола по позиции, но почемуто при такой явной установке видимости, -1 в позиции уже не влияет... странно но ладно.
хотя можеш поставить и после - UpdateScrollPos;
Prohodil Mimo (2008-02-02 23:10:00) [10]sniknik © (02.02.08 11:33) [26]
Попробовал на твоём тесте: работает без глюков (0 - нет полосы, несколько записей - полоса есть). Но это ADO.
С Query через BDE - поведение вполне устраивает, хотя я им ни когда не пользуюсь, но иногда есть желание, что бы полоса прокрутки показывалась всегда :о)
А вот поведение IBQuery, а так же DataSet из FIBPlus неесколько странно, но оно проявляется только на ХР и Vista с включёнными схемеми, если их выключить - глюк исчезнет, но опять же проверял на ХР, Vistы нет.
> введи у себя вместо имени поля звездочку "*"...
да, я вчера это заметил, с вертикальной полосой глюка нет.
Вывод один: поведение полосы прокрутки грида зависит от DataSeta. А вот кто виноват, грид или датасет - вопрос.
А можно ли грид научить не прятать полосу прокрутки, независимо от кол-ва записей?
Что у автора - я уже сам не понимаю, по началу было похоже на мой вариант, но чем больше он объяснял, тем менее понятно становилось.
sniknik (2008-02-02 11:33:00) [11]> а ты когда пробовал мой тест, какие компоненты использовал?
ADO естественно (ADOCommand, ets.), и стандартный грид с небольшими доработками.
на самом деля я даже ничего не писал, у меня уже есть программа для тестов
http://webfile.ru/1719375
и, тебя для IB понадобится провайдер данных вот это например
http://webfile.ru/1719377
строку подключения для него вводишь
Provider=IBOLE.Provider.v4;Persist Security Info=False;Data Source=D:\BORLAND\WORK\ESM\DBFS\esm_base.fdb
потом делаешь запросы, на 0 или 1 записей и на много, после одиночного выполнения жмешь кнопку истории (треугольник вниз нарисован), там под запросам будут кнопки "run" - жмешь по очереди. вот мой тест.
> Происходит следующее:
> В первом гриде, который отображает записи из TQuery, полоса прокрутки показыватся всегда, даже при 0 записях.
всегда видима, даже при 0, это легко объяснимо,
хотя именно вот это не пробовал (нет настроенного BDE алиаса как у тебя, и не хочу настраивать, + сервер IB у меня не стоит а "персонал" ограничивается одним подключением т.е. либо то либо другое поэтому закоментарил этот вариант)
проверь сам, после запроса выведи куда нибудь Query1.RecNo и Query1.RecordCount
гарантирую чтото из них будет "-1" (что значит - не поддерживается провайдером), именно в таком случае может быть описанное поведение, и полоса будет показана всегда (и от схем XP это зависеть не должно)
а вот с шириной в 1 пиксель надо будет посмотреть (действительно получил на твоем, показанном, варианте теста), хотя это и не "авторский" глюк, у него ... см. [17]
а у тебя непонятно что, может и не от винды (введи у себя вместо имени поля звездочку "*", либо набери несколько полей, так чтобы появилась горизонтальная прокрутка, глюк исчезнет. т.е. всетаки может ;)).
в общем это надо будет посмотреть.
Prohodil Mimo (2008-02-02 02:05:00) [12]Prohodil Mimo © (02.02.08 0:42) [24]
В первом гриде, который отображает записи из TQuery, полоса прокрутки показыватся всегда, даже при 0 записях.
Во второмгриде, который отображает записи из TIBQuery, полоса прокрутки:
Prohodil Mimo (2008-02-02 00:42:00) [13]sniknik © (29.01.08 16:45) [23]
а ты когда пробовал мой тест, какие компоненты использовал?
Я сейчас попробовал опять тот тест:
object Form4: TForm4
Left = 306
Top = 84
Width = 628
Height = 445
Caption = 'Form4'
Color = clBtnFace
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -15
Font.Name = 'Times New Roman'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 17
object DBGrid1: TDBGrid
Left = 32
Top = 56
Width = 569
Height = 137
DataSource = DataSource1
TabOrder = 0
TitleFont.Charset = RUSSIAN_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -15
TitleFont.Name = 'Times New Roman'
TitleFont.Style = []
end
object Button1: TButton
Left = 184
Top = 376
Width = 105
Height = 25
Caption = '0 zapisej'
TabOrder = 1
OnClick = Button1Click
end
object Button2: TButton
Left = 320
Top = 376
Width = 121
Height = 25
Caption = 'Mnogo zap.'
TabOrder = 2
OnClick = Button2Click
end
object DBGrid2: TDBGrid
Left = 32
Top = 216
Width = 569
Height = 137
DataSource = DataSource2
TabOrder = 3
TitleFont.Charset = RUSSIAN_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -15
TitleFont.Name = 'Times New Roman'
TitleFont.Style = []
end
object Query1: TQuery
DatabaseName = 'DUIS_LHG_IB'
Left = 112
Top = 16
end
object DataSource1: TDataSource
DataSet = Query1
Left = 336
Top = 16
end
object IBQuery1: TIBQuery
Database = IBDatabase1
Transaction = IBTransaction1
Left = 72
Top = 16
end
object IBDatabase1: TIBDatabase
DatabaseName = 'D:\BORLAND\WORK\ESM\DBFS\esm_base.fdb'
Left = 160
Top = 16
end
object IBTransaction1: TIBTransaction
DefaultDatabase = IBDatabase1
Left = 200
Top = 16
end
object DataSource2: TDataSource
DataSet = IBQuery1
Left = 376
Top = 16
end
end
---------------------------------------
unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables, IBDatabase, IBCustomDataSet,
IBQuery;
type
TForm4 = class(TForm)
Query1: TQuery;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Button1: TButton;
Button2: TButton;
IBQuery1: TIBQuery;
IBDatabase1: TIBDatabase;
IBTransaction1: TIBTransaction;
DBGrid2: TDBGrid;
DataSource2: TDataSource;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form4: TForm4;
implementation
{$R *.dfm}
procedure TForm4.Button1Click(Sender: TObject);
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('Select id_prf from profes Where Id_prf = 0');
Query1.Open;
ibQuery1.Close;
ibQuery1.SQL.Clear;
ibQuery1.SQL.Add('Select id_prf from profes Where Id_prf = 0');
ibQuery1.Open;
end;
procedure TForm4.Button2Click(Sender: TObject);
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('Select id_prf from profes Where Id_prf > 0');
Query1.Open;
ibQuery1.Close;
ibQuery1.SQL.Clear;
ibQuery1.SQL.Add('Select id_prf from profes Where Id_prf > 0');
ibQuery1.Open;
end;
end.
Система Win XP Home SP2 темы включены.
Delphi 2005.
Происходит следующее:
В первом гриде, который отображает записи из TQuery, полоса прокрутки показыватся всегда, даже при 0 записях.
В первом гриде, который отображает записи из TIBQuery, полоса прокрутки:
0 записей - полосы прокрутки нет.
много записей - полоса прокрутки есть.
0 записей - полосы прокрутки нет (видна её часть шириной в 1 пиксель, как будто не всё затёрлось).
много записей - полосы прокрутки нет (видна её часть шириной в 1 пиксель, при скроллировании грида видно, что бегунок перемещактся).
0 записей - полосы прокрутки нет.
много записей - полоса прокрутки есть.
....
и так по кругу.
sniknik (2008-01-29 16:45:00) [14]> Так и не понял - что не нравится ?
он. в [17], говорит, что у него все наоборот... т.е. в тесте нормально, а в его программе > 1 - нет полосы, а 0 и 1 - есть.
и притом ищет проблему в виндовс/гриде/модулях/т.д., только не в себе/своем коде.
ANB (2008-01-28 18:44:00) [15]Так и не понял - что не нравится ?
1 или 0 записей - нет вертикальной полосы прокрутки. А зачем она в таком случае нужна ?
Больше 1 - есть полоса.
Так работают и стандартный грид и эхлибовский.
sniknik (2008-01-28 18:12:00) [16]> Это виндовый глюк кеширования отрисовки неклиентской области + прямая закраска VCL-ем.
а ты внимательно читал ветку? лучше обе.
допускаю, у Prohodil Mimo возможно и был этот "виндовый глюк ...", но не у автора.
han_malign (2008-01-28 17:35:00) [17]Выключи бордеры у грида, и будет тебе щастье...
Если так уж бордеры нужны клади на панель.
Это виндовый глюк кеширования отрисовки неклиентской области + прямая закраска VCL-ем.
sniknik (2008-01-27 13:47:00) [18]> ага, один "модуль", и ты его постоянно видиш в зеркале.
думаю требуется пояснение...
вот у тебя глюк, ни у кого такого нет, никто (один человек не в счет, да и то у него судя по всему было другое) о таком не слышал... и ты спрашиваешь
> может какие - нибудь подключаемые модули
и даже не приводишь списка... помнишь, никто про твою проблему "ни сном не духом", и даже возможности увидеть чтото необычное в "подключаемых модулях" ты их лишил.
в общем то не очень то и хотелось, это в основном к стилю вопросов.
как думаешь поможет тебе ктонибудь, в таком вопросе и с такой исходной инфой?
хотя тебе самому на него ответить - дело пяти минут. у тебя есть пример с адекватной реакцией и есть прога с неадекватной, и в ней есть все подключаемые модуля... перенеси их из "глючной" в нормальную ничего другого больше не трогая и запусти. реакция стала "глючной"? значит там, убери половину, и еще раз проверь... так методом последовательного исключения ты и найдешь "чудо модуль". (в чем я глубоко сомневаюсь...)
в общем учись работать, и глюки ищи прежде всего у себя.
sniknik (2008-01-27 13:29:00) [19]> может какие - нибудь подключаемые модули могут влиять на работу грида ?
ага, один "модуль", и ты его постоянно видиш в зеркале.
учись писать правильно, читать хелпы, книги, следовать рекомендуемым методам работы и не лепи "отсебятину"... до тех пор пока не научишься понимать что и зачем делается.
AntonUSAnoV (2008-01-27 13:22:00) [20]Мда, благодарю Вас за терпимость и выдержку, позволю себе продолжить: значит сделал я этот тест, - всё работает как часы- 1 или 0 записей - пропадает прокрутка, больше 1 - появляется прокрутка, я ещё заделал третью кнопку - все записи - тоже всё путём.
Потом я сделал такие же три кнопки один в один на своей проблемной форме, и ... чуда не произошло, : 1 запись - пропадает прокрутка, все записи - не появляется, потом опять делаю тоже самое, - появляется, потом опять то же самое - не появляется, и т.д., может какие - нибудь подключаемые модули могут влиять на работу грида ? (если абсурд не ругайте)