Форум: "Начинающим";
Текущий архив: 2010.10.10;
Скачать: [xml.tar.bz2];
ВнизАртефакты HINT а Найти похожие ветки
← →
GanibalLector © (2010-07-19 14:56) [0]Добрый день.
Недавно я задавал вопрос о подсказке(hint) в TStringGrid. Сейчас есть время и я попробовал. Все работает, но появляются артефакты.
http://pics.livejournal.com/talla2k/pic/00040qd0
Достигаю я такого эффекта следующим образом: быстро двигаю мышь вверх/вниз над ячейкой.
Если просто стать над нужной ячейкой, то все в порядке.
Подскажите, в чем может быть проблема?
Код:procedure TForm_2.GridEx1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var Col, Row: Integer;
NewHint: string;
begin
GridEx1.MouseToCell(X, Y, Col, Row);
if (Row=0) and (Col in [1..10]) then
begin
case Col of
1:NewHint:="Диапазон: 8 цифр (0-99999999)";
2:NewHint:="Диапазон: 22 символа";
3:NewHint:="Диапазон: 9 цифр (0.00-9999999.99)";
…
end;
if NewHint <> GridEx1.Hint then
begin
GridEx1.Hint := NewHint;
Application.ActivateHint(GridEx1.ClientToScreen(Point(X, Y)));
end;
end else
begin
Application.HideHint;
GridEx1.Hint :="";
end;
end;
Спасибо!
← →
Юрий Зотов © (2010-07-19 16:33) [1]> GanibalLector © (19.07.10 14:56)
> Достигаю я такого эффекта следующим образом: быстро двигаю мышь
> вверх/вниз над ячейкой.
> Если просто стать над нужной ячейкой, то все в порядке.
Сколько раз в секунду вызывается Ваш обработчик, когда мышь быстро двигается над ячейкой?
И каждый раз выполняется куча одних и тех же ненужных операций, включая перерисовку хинта. Отсюда и артефакты.
После вызова MouseToCell нужно сделать примерно вот что:
1. Сравнить ячейку с ранее запомненной.
2. Если они совпали, то не делать ничего.
3. Если не совпали, то запомнить ячейку и показать хинт.
← →
GanibalLector © (2010-07-20 00:54) [2]Юрий Зотов © (19.07.10 16:33) [1]
Переделал по Вашим рекомендациям. Не помогает. Все равно артефакты! Не так часто как раньше, но есть. Причем, появляются только тогда, когда двигаю мышью из ячейки вверх (к панели быстрого запуска).
Код
private
ACol,ARow:Integer;
...
procedure TForm_8.GridEx1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var Col, Row: Integer;
NewHint: string;
begin
GridEx1.MouseToCell(X, Y, Col, Row);
if (X=0) or (Y=0) or (Col=-1) or (Row=-1) then
begin
Application.CancelHint;
Exit;
end;
begin
if (Col = ACol) and (Row = ARow) then Exit;
Application.CancelHint;
if (Row=0) and (Col in [1..3]) then
begin
//
case Col of
1:NewHint:="Диапазон: 8 цифр (0-99999999)";
2:NewHint:="Диапазон: 22 символа";
3:NewHint:="Диапазон: 9 цифр (0.00-9999999.99)";
end;
if NewHint <> GridEx1.Hint then
GridEx1.Hint := NewHint;
end else
begin
Application.CancelHint;
GridEx1.Hint :="";
end;
ACol:=Col;
ARow:=Row;
end;
end;
Кстати, а какие еще есть варианты? Может при изменении ячейки слать сообщение, по сообщению включать таймер, по срабатыванию таймера проверять координаты повторно и выводить хинт.
← →
Германн © (2010-07-20 02:17) [3]
> Может при изменении ячейки слать сообщение
Так у тебя ещё и ячейки изменяются "самопроизвольно"?
← →
sniknik © (2010-07-20 08:07) [4]надо еще одно событие обработать "маусеехит" т.е. на вывод курсора с грида, и там закрывать хинт. "моусемове" после выхода у компонента не работает, а "выключение" у тебя только в нем (а стандартное отключение хинтов видимо нестандартно включенные некорректно закрывает).
← →
GanibalLector © (2010-07-20 10:45) [5]2 sniknik © (20.07.10 08:07) [4]
Да, так и есть. Я уже сам к этому дошел. Вот...сейчас ищу как следить за выходом мыши с формы грида(панель. на панели лежит грид. и вся эта форма сидит в dll).
← →
GanibalLector © (2010-07-20 10:47) [6]>надо еще одно событие обработать "маусеехит"
MouseExit? Впервые слышу. Какие компаненты используете?
← →
sniknik © (2010-07-20 11:51) [7]> Какие компаненты используете?
никакие, "голый" vcl.
> MouseExit? Впервые слышу.
посмотри в "генофонде" на реализацию TSpeedButton.
← →
GanibalLector © (2010-07-20 12:01) [8]>посмотри в "генофонде" на реализацию TSpeedButton.
А какой версии "генофонд"? В D7 только 3 события от мыши:MouseUp, MouseMove, MouseDown. Нету у меня MouseExit
← →
sniknik © (2010-07-20 13:07) [9]> MouseUp, MouseMove, MouseDown.
это property, вот событие
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
имхо, в хелпе путаницу создают когда их так называют.
← →
GanibalLector © (2010-07-20 16:32) [10]В общем все получилось, только через одно место ))
По таймеру проверяю позицию курсора. Если курсор над гридом, то вычисляю ячейку грида. Если ячейка нужная, то создаю хинт(THintWindow) ну и удаляю хинт (если мышь покинула грид или ячейка не моя).
Код покажу позже. В порядок приведу. Может какие-нибудь неточности есть.
← →
GanibalLector © (2010-07-20 17:14) [11]
private
ACol,ARow:Integer;
FHint:THintWindow;
FHintShow:Boolean;
...
procedure TForm_8.Timer1Timer(Sender: TObject);
var h:THandle;
Rect: TRect;
X,Y,Col,Row,Tmp: Integer;
MyRect: TRect;
Banned: Boolean;
begin
// текущие координаты мыши
X:=Mouse.CursorPos.X;
Y:=Mouse.CursorPos.Y;
// получаем размеры формы в DLL
h:=GetParent(Form_8.Handle);
GetWindowRect(h,Rect);
Banned:=not ((X>Rect.Left) and (Y>Rect.Top)); // курсор над гридом?
//определяем ячеку грида под курсором
GridEx1.MouseToCell(X-Rect.Left, Y-Rect.Top, Col, Row);
// курсор все еще там же. выходим
if (Col = ACol) and (Row = ARow) then Exit;
if not Banned then // курсор над гридом. работаем
begin
if (Row=0) and (Col in [1..3]) then
begin // курсор над нужной ячейкой
if FHintShow then // автивен старый хинт?
begin // удалить старый хинт
FHint.ReleaseHandle;
FHintShow:=False;
end;
FHint:=THintWindow.Create(nil);
FHintShow:=True;
FHint.Color:=Application.HintColor;
//
case Col of
1:FHint.Hint :="Диапазон: 10 символов";
2:FHint.Hint:="Диапазон: 8 цифр (0-99999999)";
3:FHint.Hint:="Диапазон: 1 цифра (0-3)"+sLineBreak+
"0 - все операции разрешены;"+sLineBreak+
"1 - запрещен возврат;"+sLineBreak+
"2 - запрещен внос и вынос;"+sLineBreak+
"3 - запрещен возврат, внос и вынос;";
end;
// наводим красоту
MyRect:=FHint.CalcHintRect(Screen.Width, FHint.Hint, nil);
Tmp:=MyRect.Right-MyRect.Left;
MyRect.Left:=Mouse.CursorPos.X;
MyRect.Right:=MyRect.Left + tmp;
Tmp:=MyRect.Bottom-MyRect.Top;
MyRect.Top:=Mouse.CursorPos.Y+15;
MyRect.Bottom := MyRect.Top+tmp;
FHint.ActivateHint(MyRect, FHint.Hint);
end else
begin // курсор не над нужной ячейкой
if FHintShow then
begin //если хинт был, то удаляем
FHint.ReleaseHandle;
FHintShow:=False;
end;
end;
// сохранияем текущее положение курсора
ACol:=Col;
ARow:=Row;
end else
begin // курсор гуляет по форме, но НЕ над гридом
if FHintShow then
begin // если хинт был, то удаляем
FHint.ReleaseHandle;
FHintShow:=False;
end;
ACol:=-1;
ARow:=-1;
end;
end;
Достоинства:
-нет артефактов;
-хинт стоит ровно столько, сколько стоит мышьнад ячейкой (можно не спеша прочесть и подумать)
Недостатки:
-использую Timer
З.Ы. Нашли ошибку в моем коде? Не сдерживайте себя и не стесняйся в выражениях.
Всем спасибо!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.10.10;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.003 c