Click here to Skip to main content
15,887,337 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I'm in the making of a software which should send a smoothest possible scrolling command to another application. This target application is projected on a screen and loads of people will be reading text which is then scrolling.
My goal is to not have to constantly sit and manually scroll with the mouse, and to have the automatic scrolling more smooth and consistent. The smoothest scrolling I know is made when pushing the middle button which gives the arrow group icon and then panning the mouse down below. Scrolling is down on pixel level then, and using the mouse wheel (not an option) is per line.

The application waits a couple of seconds after a click, then grabs the hWnd of the active window and sends the signals to it.

Here's an extract of my code, which doesn't work. This is VB 6 code, but the question should be applicable in almost any programming language used in the windows environment.
What needs to be changed/added for it to work?
I'm more than happy for other ideas for a smooth scrolling...

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal Wparam As Long, ByRef Lparam As Any) As Long

Public Declare Function GetForegroundWindow Lib "user32" () As Long

Public Const WM_VSCROLL As Integer = &H115
Public Const SB_THUMBPOSITION = 4
Public Const SB_THUMBTRACK = 5
Public Const SB_ENDSCROLL = 8
Public Const WM_MOUSEWHEEL = &H20A 'Works but not used...

Private Sub Send_Click()
  Dim lCurHwnd As Long
  Dim lResult As Long
  
  ' Wait 2 seconds and then grab window
  Sleep 2000
  lCurHwnd = GetForegroundWindow

  'This works but is undesired:
  'SendMessage lCurHwnd, WM_MOUSEWHEEL, WHEEL_DELTA * &H10000, 50

  lResult = SendMessage(lCurHwnd, WM_VSCROLL, MakeLong(SB_THUMBPOSITION, 100), 0)
  Sleep 1000
  lResult = SendMessage(lCurHwnd, WM_VSCROLL, MakeLong(SB_THUMBTRACK, 300), 0)
  Sleep 1000
  lResult = SendMessage(lCurHwnd, WM_VSCROLL, MakeLong(SB_THUMBTRACK, 400), 0)
  Sleep 1000
  lResult = SendMessage(lCurHwnd, WM_VSCROLL, MakeLong(SB_THUMBTRACK, 500), 0)
  Sleep 1000
  lResult = SendMessage(lCurHwnd, WM_VSCROLL, SB_ENDSCROLL, 0)
End Sub


I think I might even be way off track... Having a hard time to figure out what's really the right way to send the middle-button clicks which engages the 4-way smooth pan-scrolling. I'm starting to think SB_THUMBTRACK is far off from my goal...


I have now experimented a little more and found out I may get away with somehting like this:
(C code now)
int APIENTRY WinMain(....blabla..)
  HWND hwnd;
  char buf[BUF_LEN];
  int i;

  Sleep(2000);
  hwnd = GetForegroundWindow();
  GetWindowText(hwnd, buf, BUF_LEN);
  OutputDebugString(buf);
  OutputDebugString("\n");
    
  for (i=0; i<100; i++)
  {
    ScrollWindow(hwnd, 0, 1, (RECT*) NULL, (RECT*) NULL);
    UpdateWindow(hwnd);
    Sleep(50);
  }


Yet this sends the scrolling commands to the main window under the mouse, which causes the "File" menu and everything else at the top to disappear under the title bar. A refresh doesn't fix this. I need to get a hold of the hWnd of the client part which needs to be scrolled, and is under the mouse... How?
Posted
Updated 28-Dec-09 13:28pm
v5

1 solution

You can use FindWindowEx[^] to find the main window by class name and/or text. Then you can use GetNextWindow[^] to iterate throught the child controls until you get to the control (window) you want to send scroll commands to. Spy++ is an excellent tool to use to help debug such a task.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900