JJ_Jason
JJ_Jason

Reputation: 369

Middle button click to scroll

How do I achieve this in a WinForms container control when the scroll bars are visible?

Highlighted here (Google Chrome browser):

enter image description here

EDIT: This cursor is the only one that is visible on a screenshot. I hope it's clear what i mean.

EDIT: Tried this on my control. Does not work.

    const int WM_MBUTTONDOWN = 0x207;
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_MBUTTONDOWN)
            DefWndProc(ref m);
        else
            base.WndProc(ref m);
    }

Upvotes: 2

Views: 1465

Answers (2)

C.M.
C.M.

Reputation: 1561

Here's what I have so far. It exits "reader mode" if I release the middle button, and I haven't implemented scrolling within the control (I used a textbox), but it may give you something to start with.

    [DllImport("comctl32.dll", SetLastError=true,  EntryPoint="#383")]
    static extern void DoReaderMode(ref READERMODEINFO prmi);

    public delegate bool TranslateDispatchCallbackDelegate(ref MSG lpmsg);
    public delegate bool ReaderScrollCallbackDelegate(ref READERMODEINFO prmi, int dx, int dy);

    [StructLayout(LayoutKind.Sequential)]
    public struct READERMODEINFO
    {
        public int cbSize;
        public IntPtr hwnd;
        public int fFlags;
        public IntPtr prc;
        public ReaderScrollCallbackDelegate pfnScroll;
        public TranslateDispatchCallbackDelegate fFlags2;
        public IntPtr lParam;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MSG
    {
        public IntPtr hwnd;
        public UInt32 message;
        public IntPtr wParam;
        public IntPtr lParam;
        public UInt32 time;
        public POINT pt;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int x;
        public int y;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct RECT
    {
        public int left, top, right, bottom;
    }

    private bool TranslateDispatchCallback(ref MSG lpMsg)
    {
        return false;
    }
    private bool ReaderScrollCallback(ref READERMODEINFO prmi, int dx, int dy)
    {
        // TODO: Scroll around within your control here

        return false;
    }

    private void EnterReaderMode()
    {
        READERMODEINFO readerInfo = new READERMODEINFO
        {
            hwnd = this.textBox1.Handle,
            fFlags = 0x00,
            prc = IntPtr.Zero,
            lParam = IntPtr.Zero,
            fFlags2 = new TranslateDispatchCallbackDelegate(this.TranslateDispatchCallback),
            pfnScroll = new ReaderScrollCallbackDelegate(this.ReaderScrollCallback)
        };
        readerInfo.cbSize = Marshal.SizeOf(readerInfo);

        DoReaderMode(ref readerInfo);
    }

    private void textBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Middle)
        {
            EnterReaderMode();
        }
    }

Upvotes: 2

C.M.
C.M.

Reputation: 1561

The RichTextBox control does it by default when you press the mouse wheel button.

Edit: Sorry I misunderstood and thought you were asking about doing it within a textbox not a container control

Upvotes: 0

Related Questions