Creating Custom Scrollbars

It seems that I have encountered another quagmire. I wish to create custom scrollbars. I have already created the default type, using Petzold's tutorials. So, I know the basics. However, I am looking to create something more elegant. I have studied the SCROLLINFO structure, as well as the ScrollWindowEx() and ScrollDC() functions.

However, I have been unable to find how to tie it altogether. Does someone know of a good tutorial. Or, perhaps, someone could post a simple, complete, working code that I could study. Is it better to use ScrollWindowEx() or ScrollDC()?
to make custom scrollbars:

First, how to subclass common control in a new way:
https://docs.microsoft.com/en-us/windows/win32/controls/subclassing-overview#subclassing-controls-using-comctl32dll-version-6

Before using common controls you should initialize them:
https://docs.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-initcommoncontrolsex

And link against common controls:
LINK: Comctl32.lib

To create common control supply class name to CreateWindow, for scroll bar it's
WC_SCROLLBAR

The rest is easy, subclass scroll bar and handle individual messages to customize it.
Thanks Malibor. In my studies, I haven't quite gotten to the sections on child windows and subclasses yet. Looks like I still have another hundred pages to go. You have to remember, I come from the old days of programming. My software design experience came from the days of DOS. In fact, my first software was written in Fortran, back in the 1970's. Yet, despite all of that, I feel like I'm in kindergarten with this windows stuff.
I see, but subclassing is the easiest way to make custom control.

Your question is about "custom controls", which is distinct from "common controls"
The difference is that common controls provide default functionality provided by system, which you can subclass and extend for your needs.

On the other side custom control mean absolute zero default functionality, you get a blank window which needs to be turned into a control, therefore much more work to do.

Subclassing is far easier, and scrollbar is indeed a child window.

For example to create ScrollBar:

1
2
3
4
5
6
7
8
9
10
11
12
HWND hWnd = CreateWindowExW(
	WS_EX_LEFT,
	WC_SCROLLBAR,
	nullptr,
	WS_CHILD,
	x, y,
	width,
	height,
	hParent,   // parent window ex. your main window
	reinterpret_cast<HMENU>(ctrl_ID)),   // scrollbar ID number
	GetModuleHandleW(nullptr),
	nullptr);


This is subclass procedure to handle custom control messages:
1
2
3
4
5
6
7
8
9
10
LRESULT SubClassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam,  UINT_PTR SubclassID, DWORD_PTR ref_data)
{
         // UnSublcass when done
         if (msg == WM_NCDESTROY)
                 RemoveWindowSubclass(hWnd, SubclassProc, 1);

         // handle messages or just do the default
         // note that you call DefSubclassProc not DefWindowProc
         return DefSubclassProc(hWnd, msg, wParam, lParam);
}


And then to subclass it: (note that you don't need to register window)

SetWindowSubclass(hWnd , SubClassProc, 1, nullptr);

And that's it, run message loop and handle messages in SubClassProc

You can't have it more simple than that.

EDIT:
Ah ofc. before all this you need to load the common control library for scrollbars, here is
how to do it:

1
2
3
4
5
6
INITCOMMONCONTROLSEX ctrl;

ctrl.dwSize = sizeof(INITCOMMONCONTROLSEX);
ctrl.dwICC = ICC_BAR_CLASSES;

InitCommonControlsEx(&ctrl);
Last edited on
Thanks Malibor. Sorry about taking so long to get back. I had a household repair crisis--I had to fix the TV. A 46" flatscreen is no feather!

I have been studying your bit of code. The method is completely different than what I have been reading about scrollbars. Does this mean that each scrollbar is a child window unto itself? Has the use of the SCROLLINFO structure been superseded? Or, is this what is needed to implement the SCROLLINFO structure?

I swear, with this Windows stuff, I feel like I'm spinning my wheels. For example, I wanted to work with bitmaps. So, I started leaning to use GDI, only to discover that it had been superseded by GDI+. So, I start learning GDI+, only to be told that it had been superseded by Direct2D. Is there no end? Now, my brain is too tired to try to learn Direct2D. Am I running into the same issue with scrollbars?
Last edited on
anachronon wrote:
Is there no end?

Yes, there is no end...Windows UI 3.0 Library (WinUI) is coming around the corner...
https://docs.microsoft.com/en-us/windows/apps/winui/
Windows UI 3.0 Library (WinUI) is coming around the corner...
https://docs.microsoft.com/en-us/windows/apps/winui/


wow, I didn't know this exists, at first it looks like something that we all wait but...,
as I read the docs this sounds like just another MS attempt to attract developers toward it's "universal windows", XBOX and MS related languages and toward "modern way of doing things". aahh...

I've take a quick look on how to create a button here:
https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/buttons

Nice example how to make it in C# or XAML (lol) thanks MS, but maybe some other time...

And with support for both Win32 and UWP apps, you can build with WinUI from the ground up or migrate your existing MFC, WinForms, or WPF apps at your own pace and using familiar languages such as C++, C#, Visual Basic, and even Javascript


Exactly! MS wants people to *migrate* to XBOX and Window Phone.
malibor wrote:
as I read the docs this sounds like just another MS attempt to attract developers toward it's "universal windows"


"WinUI 3 is the next version of WinUI, a native Windows 10 UI platform completely decoupled from the UWP SDK."...it's separating the UI from UWP so you can use WinUI for WinAPI projects.

Anyway, Build 2020 has apparently announced a project to unify the development experience or something (still need to read up on it). It's about time, it's a complete mess at the moment.

Edit:

"A big part of Project Reunion is WinUI 3..." maybe it's just a new name for what they have been working on. 🤷‍♂️
Last edited on
Registered users can post here. Sign in or register to post.