Page 1 of 1
Scrollbar Popup Menu
Posted: Thu Jul 18, 2024 10:04 pm
by standay
Sergey,
Would you have any idea on how to get a popupmenu to show when the rve vertical scrollbar is right clicked? I've looked all over and tried things and nothing works. Just wondered if you had any ideas.
Thanks
Stan
Re: Scrollbar Popup Menu
Posted: Fri Jul 19, 2024 10:28 am
by Sergey Tkachenko
AFAIK, it can be implemented by handling WM_NCRBUTTONDOWN message in rve. But TRichView does not process this message, so it can be done only in an inherited component.
Or you can hide a scrollbar (VScrollVisible = False) and use your own external scrollbar instead.
Re: Scrollbar Popup Menu
Posted: Fri Jul 19, 2024 3:15 pm
by standay
Hi Sergey,
Yes, WM_NCRBUTTONDOWN (along with a HitTest check) works. My app already lets me choose between using a native scrollbar or an external one. Adding a popup to the external one is easy, but I was stumped with how to add it to the native scrollbar.
Here's what I did in case someone else wants to try it. I just subclassed the rve so I didn't have to make a new component:
Code: Select all
type
TRichViewEdit = class( RVEdit.TRichViewEdit )
private
procedure WMNCRButtonDown(var Msg : TWMNCRButtonDown); message WM_NCRBUTTONDOWN;
end;
...
//http://www.delphicorner.f9.co.uk/articles/forms3.htm
procedure TRichViewEdit.WMNCRButtonDown(var Msg : TWMNCRButtonDown);
begin
if Form1.rve.VScrollVisible then
if (Msg.HitTest = HTVSCROLL) then
begin
Form1.PopupMenu1.Popup( Mouse.CursorPos.X,Mouse.CursorPos.Y );
end;
if Form1.rve.HScrollVisible then
if (Msg.HitTest = HTHSCROLL) then
begin
Form1.PopupMenu1.Popup( Mouse.CursorPos.X,Mouse.CursorPos.Y );
end;
end;
Works great and is just what I was after. Thanks again.
Stan
Re: Scrollbar Popup Menu
Posted: Fri Jul 26, 2024 12:15 pm
by standay
Hi Sergey,
Probably no one cares about this but I thought I'd post a follow up. While subclassing the TRichViewEdit let me show a popupmenu when right-clicking the rve scrollbar, it was causing some unintended problems elsewhere in my app. It would work OK in a simple project, but my project is not a simple one.
So I did this instead. Since the rve sends the WM_NCRBUTTONDOWN out when its scrollbar is clicked, I handled that message in an appication events message event instead of the rve itself.
Code: Select all
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
var
Pt: TPoint;
r: TRect;
begin
//Processing WM_NCRBUTTONDOWN this way let me put a popupmenu on the native OS scrollbar.
//Panel7 is the rve parent component
Pt := Panel7.ScreenToClient( Mouse.CursorPos );
r := Panel7.ClientRect;
if Msg.message = WM_NCRBUTTONDOWN then
begin
r := Panel7.ClientRect;
//Restrict this to just the vertical scrollbar:
r.Left := r.Right - GetSystemMetrics( SM_CYVSCROLL );
if PtInRect( r, Pt ) then
begin
//ReleaseCapture; //So far, not needed...
//Only show the scroll popup if the native OS scrollbar is visible:
if Form1.rve.VScrollVisible then
begin
//Use if VScrollMax > 0 here if you only want to show the popup
//if it is active.
ScrollPopup.Popup( Mouse.CursorPos.X,Mouse.CursorPos.Y );
end;
//The key to making this work: Shut off this message:
Handled := true;
end;
end;
This now works without subclassing or making a new component. Maybe it will help someone else wanting to do this.
Stan