Scrollbar Popup Menu

General TRichView support forum. Please post your questions here
Post Reply
standay
Posts: 272
Joined: Fri Jun 18, 2021 3:07 pm

Scrollbar Popup Menu

Post 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
Sergey Tkachenko
Site Admin
Posts: 17521
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Scrollbar Popup Menu

Post 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.
standay
Posts: 272
Joined: Fri Jun 18, 2021 3:07 pm

Re: Scrollbar Popup Menu

Post 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
standay
Posts: 272
Joined: Fri Jun 18, 2021 3:07 pm

Re: Scrollbar Popup Menu

Post 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
Post Reply