Определение позиции Memoview под курсором
Поискав по форуму, не нашёл описания того, как определить, какой MemoView находится под курсором мыши.
Пришлось писать свой метод.
К сожалению, определение координат Memo зашито жёстко в исходниках, и наружу эти методы не выходят.
В примере мне нужно было вызвать PopupMenu, только если под ним находится Memo.
Предполагается, что frxPreview1 уже лежит на форме.
Прежде всего, в разделе Type задаём "ломалку" недоступных полей компонента TfrxPreviewWorkspace
Далее сама функция:
Current_Memo - это компонент TfrxMemoView, относительно которого предполагается проверять положение курсора мыши. У меня этот компонент выделяется цветом и копируется в глобальные переменные формы в методе frxReport1.onMouseOverObject(). Вы можете выбрать другой способ определения этого Memo, можно даже в цикле по всем компонентам frxReport1.
Пришлось писать свой метод.
К сожалению, определение координат Memo зашито жёстко в исходниках, и наружу эти методы не выходят.
В примере мне нужно было вызвать PopupMenu, только если под ним находится Memo.
Предполагается, что frxPreview1 уже лежит на форме.
Прежде всего, в разделе Type задаём "ломалку" недоступных полей компонента TfrxPreviewWorkspace
type
THackfrxPreviewWorkspace = class(TfrxPreviewWorkspace)
private
FOffset: TPoint;
FPageList: TfrxPageList;
end;
...
Далее сама функция:
procedure TForm1.frxPreview1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Scale: Extended;
PageNo: Integer;
PageBounds: TRect;
FOffset: TPoint;
p: TPoint;
VertScrollPosition: Integer;
// Функция "выдрана" из frxPreviewPages.pas - TfrxPreviewPages.ObjectOver()
function MouseInView(c: TfrxComponent): Boolean;
var
r: TRect;
begin
with c do
r := Rect(Round(AbsLeft * Scale), Round(AbsTop * Scale),
Round((AbsLeft + Width) * Scale), Round((AbsTop + height) * Scale));
OffsetRect(r, Round(FOffset.X), Round(FOffset.Y));
Result := PtInRect(r, Point(X, Y));
end;
begin
GetCursorPos(p);
// popup menu
if Button = mbRight then
begin
Scale := frxPreview1.Workspace.Zoom;
PageNo := frxPreview1.Workspace.PageNo - 1;
FOffset := THackfrxPreviewWorkspace(frxPreview1.Workspace).FOffset;
VertScrollPosition := frxPreview1.Workspace.VertPosition;
// Почему-то без + 10 работает неверно:
PageBounds.Left := 10 + Round
(frxPreview1.PreviewPages.Page[PageNo].LeftMargin * fr01cm * Scale);
PageBounds.Top := 10 + Round
(frxPreview1.PreviewPages.Page[PageNo].TopMargin * fr01cm * Scale);
FOffset.X := PageBounds.Left - FOffset.X;
FOffset.Y := PageBounds.Top - FOffset.Y - VertScrollPosition;
if Assigned(Current_Memo) then
if MouseInView(Current_Memo) then
begin
PopupMenu1.Popup(p.X, p.Y);
end;
end;
end;
Current_Memo - это компонент TfrxMemoView, относительно которого предполагается проверять положение курсора мыши. У меня этот компонент выделяется цветом и копируется в глобальные переменные формы в методе frxReport1.onMouseOverObject(). Вы можете выбрать другой способ определения этого Memo, можно даже в цикле по всем компонентам frxReport1.