How to scroll Window in other process with Win32API

You could send a WM_MOUSEWHEEL message to do what you want. For example, to scroll down once in a new notepad window using C++:

HWND hwnd = FindWindowEx(FindWindow(NULL, "Untitled - Notepad"), NULL, "Edit", NULL);
RECT r;
GetClientRect(hwnd, &r);
SendMessage(hwnd, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA * -1), MAKELPARAM(r.right / 2, r.bottom / 2));

To adapt that to C#, you could do something such as this:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, ref Point lParam);

private void ScrollWindow(IntPtr hwnd, Point p, int scrolls = -1)
{
    SendMessage(hwnd, WM_MOUSEWHEEL, (WHEEL_DELTA * scrolls) << 16, ref p);
}

Which could be used to scroll down once in a new notepad window like this:

//Imports
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
...
//Actual code
IntPtr hwnd = FindWindowEx(FindWindow(null, "Untitled - Notepad"), IntPtr.Zero, "Edit", null);
Point p = new Point(0, 0);
ScrollWindow(hwnd, p);

Some programs will require the lParam sent to be a point that's actually above the scrolled area, while others such as notepad will not.


If you're trying to scroll the window of another process, you need to, in effect, simulate clicks on the scroll bar or key presses. The cleanest way to do that is to use UI Automation, which has both .NET and native interfaces.

By asking for the scrollbar info, you're simply getting information about how the scrollbar is displayed. That's not going to give you a way to scroll the window content. You have to get the target application to scroll the content by making it think the user is operating the scrollbar.

Tags:

C#

Winapi