I have searched the world wide web without a proper answer.
In my Windows Form application, i want to change the width of a scrollbar that belongs to a FlowLayoutPan
Cody Gray's answer is 100% correct, though I wanted to add more reference material on the subject matter.
The way that Windows Forms creates scrollbars is through using the window styles WS_HSCROLL and WS_VSCROLL. Respectively, these styles are responsible for enabling the horizontal and vertical scrollbars for a given HWND. An HWND is a native resource handle to a "window", which in .NET lingo corresponds to a Control.
Thinking from a Windows API perspective, we must set window styles at the time we create the HWND. This is done through a call to CreateWindow, CreateWindowEx, or SetWindowLong. Naturally, we may begin to think about using P/Invoke to help us out, but this would be quite a burden as it means we would need to re-implement Windows Forms from scratch.
Fortunately, Windows Forms exposes a property, CreateParams, that can be overridden to specify the exact window styles, among other Control creation parameters. This property is in turn consumed by the .NET framework so that it can create the HWND with the appropriate styles when the Control is instantiated.
Replacing the Windows API functionality for a scrollbar is actually simpler than it may seem; however, this isn't obvious (well for me anyways, I had to sift through .NET source to find the answer). To do this, we must choose the appropriate Control to inherit from to create our own custom ScrollableControl. If we observe the source code for System.Windows.Forms.ScrollableControl, we see the following styles are used:
CreateParams cp = base.CreateParams;
if (HScroll || HorizontalScroll.Visible) {
cp.Style |= NativeMethods.WS_HSCROLL;
}
else {
cp.Style &= (~NativeMethods.WS_HSCROLL);
}
if (VScroll || VerticalScroll.Visible) {
cp.Style |= NativeMethods.WS_VSCROLL;
}
else {
cp.Style &= (~NativeMethods.WS_VSCROLL);
}
So, in short, when we extend from ScrollableControl, the native horizontal and vertical scrollbars are enabled based on its internal logic. We could access the ScrollableControl's window handle and then call SetWindowLong to hide the scrollbars; however, we would need to keep track of all places that ScrollableControl interacts with the Windows API. In fact, there is an internal function Control.UpdateStylesCore() that is called based on whether or not the scrollbars should be shown. This function effectively reapplies the windows styles above, and it would likely be best not to fight with it. It would be a much cleaner approach to steer away from the Windows API and extend directly from Control. We can then provide whatever API's we desire to have.
This means we would be looking at re-implementing:
Alternatively, a simple approach might be to create a new UserControl. This would allow us to use the Visual Studio designer to simplify configuring our scrollbar buttons and tracks.
Whichever path is taken, it will be necessary to see how ScrollableControl works internally in order to provide a comfortable user-experience.