I am attempting to retrieve scroll information from the window handle, but I keep getting a value of 0. I am pursuing this approach because my goal is to capture a complete scrolling screenshot of the window. The intention is to enable automatic scrolling and image capture. While I have successfully implemented automatic window scrolling, I’ve encountered variations in the scrolling behaviour for different windows.
For instance, sending a mouse delta of 100 results in Chrome scrolling by around 70 pixels, whereas Visual Studio scrolls by approximately 110 pixels. Each window appears to exhibit distinct scrolling characteristics. Therefore, my current objective is to calculate the precise amount of pixel movement during scrolling using the scrollbar. However, I have encountered difficulties in achieving this functionality.
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct SCROLLINFO
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
public enum ScrollInfoMask : uint
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS),
}
public enum SBOrientation : int
{
SB_HORZ = 0x0,
SB_VERT = 0x1,
SB_CTL = 0x2,
SB_BOTH = 0x3
}
// get scrollbar info
SCROLLINFO scrollinfo = new SCROLLINFO();
scrollinfo.cbSize = (uint)Marshal.SizeOf(typeof(SCROLLINFO));
scrollinfo.fMask = (uint)ScrollInfoMask.SIF_ALL; // or SIF_PAGE | SIF_POS, etc.
bool success = GetScrollInfo(hWnd, (int)SBOrientation.SB_VERT, ref scrollinfo);
if (success)
{
// Process scrollinfo here
}
else
{
// Handle error here
}
uint errorCode = GetLastError();
Console.WriteLine($"Failed to retrieve scroll info. Error code: {errorCode}");
[DllImport("user32.dll")]
public static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, ref SCROLLINFO lpsi);
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
Getting "False" from GetScrollInfo
and GetLastError() returns 1447 error code
It’s working on Notepad Window… but not working on Chrome, Firefox, visual studio etc
"I’m essentially looking to capture scrolling screenshots. I have two options:
Automatically scroll through the content using code and calculate the distance scrolled in pixels. Then, I’ll capture that specific portion and append it to the image.
Alternatively, I can scroll a predefined height. This way, if I scroll 100 pixels, for instance, I’ll capture an image of exactly 100 pixels.
I’m currently attempting option 1, but I haven’t been successful so far."
2
Answers
Make sure you initialize the
SCROLLINFO
structure properly before using it.And handle
return
value ofGetScrollInfo
: TheGetScrollInfo
function returns a boolean indicating success or failure. Make sure you’re checking this return value to ensure that the scroll information is indeed being retrieved.Use the Right Scroll Bar Constant: The
fnBar
parameter in theGetScrollInfo
function indicates whether you’re querying the horizontal or vertical scrollbar. Make sure you’re using the correct constant values:SB_HORZ
for horizontal andSB_VERT
for vertical scrollbars.There are no scrollbars…
These days you rarely see modern applications with
native
scrollbars.Visual Studio
has one single top-level native window handle (aHWND
). The top-level window could theoretically have a scrollbar, but usually will not.…just pixels!
Now, when you see those scrollbars in, what appears to be child windows, in e.g.
Visual Studio
andChrome
, chances are that those are just rendered pixels. I.e. There is no native scrollbar to look for.Since we know that
Visual Studio
is a WPF application, we can get hold of scrollbar information using someWPF
related tricks. Obviously, such tricks will not work for non-WPF applications (likeChrome
). ForChrome
there might be some way to read the DOM outside the browser, but expect it to be non-trivial.