2

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);
    }
JJ_Jason
  • 349
  • 8
  • 24
  • possible duplicate of [middle-button scrolly thing in textbox](http://stackoverflow.com/questions/1528934/middle-button-scrolly-thing-in-textbox) – CodeCaster Nov 06 '12 at 14:33
  • I tried that code posted by CodeCaster too and it didn't work. I tried checking for all sorts of messages other than WM_MBUTTONDOWN too and none worked. – C.M. Nov 06 '12 at 14:49
  • The VB.Net sample posted by Krantz under [this question](http://stackoverflow.com/questions/6267380/enable-readermode-in-net-control-pinvoke-doreadermode-api) worked for entering reader mode for me. – C.M. Nov 06 '12 at 15:45

2 Answers2

2

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();
        }
    }
C.M.
  • 1,474
  • 13
  • 16
  • This is ok, but you already stated that this is enabled by default on a **rich**textbox so i fail to see the point here. Also, a parent control (a container) doesn't register mouse down. – JJ_Jason Nov 06 '12 at 16:36
  • (A parent control filled with children) – JJ_Jason Nov 06 '12 at 16:49
0

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

C.M.
  • 1,474
  • 13
  • 16