简体   繁体   中英

C# is there a better way to hide horizontal scroll bar using WinAPI messages?

I have a class IndicatorPanel: FlowLayoutPanel that displays custom controls. When this panel is resized it also resizes its child controls widths to be the same size as its width. This is so that it never needs to show a horizontal scroll bar.

The issue I had was that without AutoScroll = true I had to re-implement all of the scroll functionality if I wanted a vertical scroll bar but it made it so a horizontal never appeared. I decided to go the other way and try to hide the horizontal scroll bar continually in WndProc and use auto scroll for the vertical scroll bar.

Here is my WndProc

const int WM_MOUSEWHEEL = 0x020A;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);

private enum ScrollBarDir { SB_HORZ = 0, SB_VERT = 1, SB_CTL = 2, SB_BOTH = 3 }
protected override void WndProc(ref Message m)
{
    // Continually suppress; AutoScroll wants to show a scroll bar
    ShowScrollBar(this.Handle, (int)ScrollBarDir.SB_HORZ, false);
    // No scrolling when that flag is set
    if (m.Msg == WM_MOUSEWHEEL && NoScrollFlag)
        return;
    // Pass everything else through
    base.WndProc(ref m);
}

As you can see this is a little overboard. Anytime a message comes in the first thing that happens is I call the ShowScrollBar function to suppress the horizontal scroll bar, which more often than not is doing nothing but wasting cycles.

Is there a windows message I can catch so that I only call ShowScrollBar when it is needed?

I have looked through the windows scroll bar reference and none of the messages seem to apply to this, they all have to do with controlling a scroll bar after it is drawn/added to a control/form.

Execute your code to hide the horizontal scrollbar in response to WM_NCCALCSIZE Windows message

Sent when the size and position of a window's client area must be calculated. By processing this message, an application can control the content of the window's client area when the size or position of the window changes.

https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-nccalcsize

 Const WM_NCCALCSIZE As Integer = &H83

    Protected Overrides Sub WndProc(ByRef m As Message)

        If m.Msg = WM_NCCALCSIZE Then
            ShowScrollBar(Me.Handle, CInt(ScrollBarDir.SB_HORZ), False)
        End If

        MyBase.WndProc(m)

    End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM