Today vanity caught up with me and I decided to add myself to the list of “major contributors” shown on the GExperts About dialog. But this list has become rather long over the years (actually it is surprisingly short given the time GExperts has been in existence), so only the top few names are visible. Since the list is alphabetically sorted by last names, unfortunately my name, together with the ones of such notables as Stefan Hoffeister, Ray Lischner or Martin Waldenburg was only visible when scrolling down the list. And let’s be honest: Nobody scrolls down that list.

So, we’ll scroll the list for you, you lazy basterd™.

Basically, it’s quite simple: Use a timer to periodically send a WM_VSCROLL message to the memo with wParam = SB_LINEDOWN to scroll down one line:

procedure TfmAbout.tim_ScrollTimer(Sender: TObject); begin inherited; SendMessage(mmoContributors.Handle, WM_VSCROLL, SB_LINEDOWN, 0); end;

But what do we do when we reach the end of the list? We could stop, we could revert the scrolling direction, or we jump to the top again. I decided to do the latter.

But how do you know when you reached the end? I thought that this can probably be determined from the SendMessage return value, but MSDN states only

Return value If an application processes this message, it should return zero.

Which I thought odd, so I just tried it and guess what? you have reached the end, when the function returns 0.

procedure TfmAbout.tim_ScrollTimer(Sender: TObject); var Res: Integer; begin inherited; Res := SendMessage(mmoContributors.Handle, WM_VSCROLL, SB_LINEDOWN, 0); if Res = 0 then begin // we have reached the end SendMessage(mmoContributors.Handle, WM_VSCROLL, SB_TOP, 0); end; end;