4

I have created my own custom drawn list with checkboxesin WTL, I want to make it scrollable now, the thing is that I am subclassing a Static Text control over which I draw.. And I don't know if static controls support scrolling in any way.. Anyway my question is how do I make my custom made controll scrollable, do I have to impement the mechanism myself?

AlexandruC
  • 3,527
  • 6
  • 51
  • 80

2 Answers2

6

Yes, you'll have to implement it entirely by hand. That's the drawback of not using a built-in control. It probably would have been a better idea to start off with a ListBox and then customize that to your desire. That way, you would get all of the scrolling, selection, and other logic for free.

The steps are roughly as follows (there are probably ATL/WTL idioms for some or all of these, but any ATL/WTL programmer can convert back and forth from raw Win32):

  1. Add the WS_HSCROLL and/or WS_VSCROLL window styles to your custom static control, depending on if you want a horizontal, vertical, or both scroll bars. You would add these to list of window styles passed in to the CreateWindow/CreateWindowEx function.

  2. By default, those scroll bars won't do anything at all. You need to tell them what to do using the SetScrollInfo function. In your case:

    • The first parameter (hwnd) would be the handle to your control window.
    • The second parameter (fnBar) should be either SB_HORZ to adjust the horizontal scroll bar, or SB_VERT to adjust the vertical scroll bar.
    • The third parameter (lpsi) is a pointer to a SCROLLINFO structure, filled in with the desired scrolling parameters, including the current position of the thumb, the minimum and maximum values, and the "page" size used to set up the proportional scroll bar.
    • The fourth parameter (fRedraw) should probably be set to TRUE.

  3. You will also need the EnableScrollBar function to enable/disable the scroll bar as appropriate. Like the previous function,

    • hwnd is a handle to your control window
    • wSBflags is either SB_HORZ, SB_VERT, or SB_BOTH
    • wArrows is one of the ESB_* values, depending on what you want

  4. Finally, you will want to write code in your custom control's window procedure to handle the WM_HSCROLL and/or WM_VSCROLL messages. These are sent to the window whenever the scroll bar is moved. Inside of the handler for these messages, you will want to do the following things to update the control's state:

    • Call the SetScrollInfo function to update the thumb to its new position
    • Redraw the contents of your control in accordance with the scrolled distance. There are multiple ways of doing this, but I'd probably use the ScrollWindowEx function.

    The custom control's window procedure will also need to handle the WM_SIZE message to update the scroll bar state (by calling SetScrollInfo and/or EnableScrollBar) in response to changes in the window's size.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 1
    This is all great, but there also is `CScrollImpl` in WTL which covers a great deal of complexity for a custom control. – Roman R. Aug 11 '13 at 15:01
  • I also trying this approach , I followed steps 1,2,3 and 4, and now when i get the WM_VSCROLL I do a SetSCrollInfo and a call to ::ScrollWindowEx(m_hWnd, 0, value, NULL, NULL, NULL, NULL, SW_INVALIDATE | SW_ERASE); but nothing yet, I am not calling it correctly? before that func call I do a SetRedraw(FALSe) and after it a SetRedraw(TRUE) – AlexandruC Aug 12 '13 at 17:20
  • GetLastError() returns 0; – AlexandruC Aug 12 '13 at 19:08
  • and I am drawing my control using a CMemoryDC and gdiplus – AlexandruC Aug 12 '13 at 19:14
  • I've felt out the WM_PAINT.. should ScrollWindowEx simply scroll the text inside the Static control? – AlexandruC Aug 13 '13 at 15:38
  • ANYWAY, ScrollWindowEx was of no use, it didn t worked for me, I just modified the drawing procedure so it adds an offset to the items that I draw according to the value that I get in WM_VSCROLL, I don't know why... I really couldn t figure out how this functions really works.. I got the desired end result, but I m not sure that this is the correct approach. I 've used your method because I'm continuing a project that was built upon this approach of scrolling. Thank you both for your time. – AlexandruC Aug 13 '13 at 17:49
6

Cody Gray provided excellent introduction into adding support for scrolling, however what you also have is the help from the WTL itself.

WTL's atlscrl.h offers you classes to inherit from and implement a custom window/control with scrolling.

// Classes in this file:
//
// CScrollImpl<T>
// CScrollWindowImpl<T, TBase, TWinTraits>
// CMapScrollImpl<T>
// CMapScrollWindowImpl<T, TBase, TWinTraits>
// CFSBWindowT<TBase>
// CZoomScrollImpl<T>
// CZoomScrollWindowImpl<T, TBase, TWinTraits>
// CScrollContainerImpl<T, TBase, TWinTraits>
// CScrollContainer

Not so much code/snippets around to demo the use, but there is still one WTL sample that covers the basics and it should be a good starting point for you as well. \Samples\BmpView has a class for scrollable bitmap:

class CBitmapView : 
  public CScrollWindowImpl<CBitmapView>
{
public:

You will see it's really small and it covers most of the complexity.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • Great, thanks for posting this. Can you tell I don't use WTL? :-) – Cody Gray - on strike Aug 11 '13 at 15:15
  • Thank you both for two great answers! – AlexandruC Aug 11 '13 at 15:21
  • For the moment I am looking at CScrollImpl because it seems easier. – AlexandruC Aug 11 '13 at 15:22
  • @CodyGray: This is understandable :) WTL is banished and abandoned, still scrolling is something it can do. – Roman R. Aug 11 '13 at 15:23
  • @A.K: Most likely you still need `CScrollWindowImpl`. `CScrollImpl` is just a helper part of it detached from `HWND` and actual window class. – Roman R. Aug 11 '13 at 15:24
  • It seems that I'm not having a lot of luck with this. I've edited my question to include the problem. And if WTL is abandoned what do people use these days to create fully customized interfaces in c++ ?(just out of curiosity) – AlexandruC Aug 11 '13 at 16:05
  • @A.K: Have a better look at `\Samples\BmpView\view.h`. `CStatic` is not a valid base in `CScrollWindowImpl`. – Roman R. Aug 11 '13 at 16:33
  • 3
    "What do people use these days to create fully customized interfaces in C++". I like WTL, but it's definitely not mainstream. I suppose that mainstream is cross platform UI frameworks typically producing ugly UI and bad UX, and .NET which is nowhere near C++. – Roman R. Aug 11 '13 at 17:18
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/35308/discussion-between-a-k-and-roman-r) – AlexandruC Aug 12 '13 at 19:14
  • I have a hard one http://stackoverflow.com/questions/18336005/wtl-multithreading-multiple-interfaces-libraries – AlexandruC Aug 20 '13 at 13:12