Call to "GetScrollInfo" Win API with C#


Anyone know why this call to GetScrollInfo returns false?

        public struct SCROLLINFO
            public int cbSize;
            public int fMask;
            public int nMin;
            public int nMax;
            public int nPage;
            public int nPos;
            public int nTrackPos;


        private static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO ScrollInfo);

        private const int SB_HORZ = 0;
        private const int SB_VERT = 1;
        private const int SB_CTL = 2;
        private const int SB_BOTH = 3;

            hWnd = new IntPtr(3083266);                                // I've hardcoded a handle here for simplicity.

            SCROLLINFO scrollInfo = new SCROLLINFO();

            GetScrollInfo(hWnd, SB_VERT, ref scrollInfo);
            MessageBox.Show("nPage: " + scrollInfo.nPage.ToString() + "\n\n" + "nPos: " + scrollInfo.nPos.ToString() + "\n\n" + "nMax: " + scrollInfo.nMax.ToString() + "\n\n");

GetScrollInfo returns 0 (for a loads of different window handles i've tried (all of which seem to have a scroll bar)). And all the values used above are 0.

I tried a call to GetLastError, but that too returned 0.            
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:

        [DllImport("User32.dll", EntryPoint = "GetScrollInfo")]
        public static extern bool GetScrollInfo([In]IntPtr hwnd, [In]int fnBar, [In, Out]ref SCROLLINFO lpsi);

        private const int SB_VERT = 0x1;
        private const int SB_HORZ = 0x0;
        private const int SIF_PAGE = 0x2;
        private const int SIF_POS = 0x4;
        private const int SIF_RANGE = 0x1;
        private const int SIF_TRACKPOS = 0x10;
        private const int SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS);

        private void button1_Click(object sender, EventArgs e)
            SCROLLINFO si = new SCROLLINFO();
            si.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(si);
            si.fMask = SIF_ALL;

            GetScrollInfo(this.Handle, SB_VERT, ref si);

            MessageBox.Show("nPage: " + si.nPage.ToString() + "\n\n"
                + "nPos: " + si.nPos.ToString() + "\n\n" +
                "nMax: " + si.nMax.ToString() + "\n\n");

saltedAuthor Commented:
That's still not returning a value.

Does it for you? Is there a common window you've got working wiht that code i could try?

I've tried it with parts of Visual Studio, Firefox and the Internet Explorer_Server class, they all return zeros.
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
Yes...I'm getting return values.

"Is there a common window you've got working wiht that code i could try?"

I'm using MY window from my C# app:

    GetScrollInfo(this.Handle, SB_VERT, ref si);

this.Handle gets a handle to the window that contains "button1"...but it would work with any valid window handle that has scrollbars on it.
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

saltedAuthor Commented:
OK, thanks for your help so far Idle_Mind, I've been doing some investiagting with Spy++ and i think i know why it's not working.

If you spy any window other than a .Net ones and Windows Explorer, it doesn't have the style "WS_VSCROLL" - even windows i *know* have a vertical scroll bar. Even Internet Explorer doesn't do it! It just has:

Any ideas?
saltedAuthor Commented:
Sorry, I meant "... even 'Internet Explorer_Server' doesn't do it...."

But i also tested every window from the parent 'IEFrame' down.
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
I'm not sure how Internet Explorer is putting scrollbars on it's pages.

For some applications the Scrollbars are actually on a CHILD window and not the main window.  For instance, NotePad has one child window with a class name of "Edit" and it has the scrollbars instead of the main window.  You may have to use the FindWindowEx() API to get a handle to the correct child window.

What application specifically are you trying to do this with?  Perhaps someone knows a more efficient way to achieve your end goal...

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
saltedAuthor Commented:
Well, in this case it's Firefox, but i'll need to do it with other browsers as well.

I've been through every child window on both firefox and IE. None of them have the style "WS_VSCROLL". Whereas, like you say, one of Notepad's child windows does have "WS_VSCROLL".

The msdn documentation makes no mention of any other way of creating/controlling scroll bars in windows - so how are IE and the these other apps creating scroll bars?

It also stops ScrollInfo from working.
Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
This is definitely NOT my forte!    =\

It may be possible to get the scrollbar info from IE via automation:

Though I don't have enough experience to get it myself...

// COM References to "Microsoft Internet Controls" and "Microsoft HTLML ... Library"

using mshtml;

        private SHDocVw.InternetExplorer IE;

        private void button3_Click(object sender, EventArgs e)
            IE = new SHDocVw.InternetExplorer();
            IE.DocumentComplete += new SHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(IE_DocumentComplete);
            IE.Visible = true;
            Object o = null;
            IE.Navigate("", ref o, ref o, ref o, ref o);

        void IE_DocumentComplete(object pDisp, ref object URL)
            HTMLDocumentClass html = (HTMLDocumentClass)(IE.Document);
Bob LearnedCommented:
For Internet Explorer, I believe that you need to find the handle for the 'Shell DocObject View'.  These are the window class names for an Internet Explorer page (

Google - Microsoft Internet Explorer
  Shell DocObject View
  Internet Explorer_Server

saltedAuthor Commented:
Yeah, I've done the IE automation way for IE already, got that working perfectly. It's the other apps that are causing the problem.

Thanks again for all your help :) If i don't get an answer soon, i'll close this question (giving you the points) and start another including what i've learnt so far. This question has been moved to C# (because it was originally a c# question because I thought i'd got something wrong in my code), but really i need some help with general windows/API stuff now.

I wonder if it's anything to do with this:

"Microsoft Internet Explorer 4.0 introduces a new control called a flat scroll bar. Functionally, flat scroll bars behave just like standard scroll bars. The difference is that you can customize the appearance of flat scroll bars to a greater extent than standard scroll bars."

I guess it's possible that these flat scroll bars are being used by the apps that don't register "WS_VSCROLL" and use some other scroll bar method...

I also wonder if this stuff is anyone's forte! But i feel like i'm getting close to a solution here - there must be a way of querying the full page length of a window with a scroll bar. The traditional way doesn't work, but there must be something i'm missing.

I've been all the way through the MSDN ScrollBars documentation. All the methods seem to rely (although they don't always explicitly say it) on WS_VSCROLL being registered as a style. This seems a bit odd.

Also, I've noticed a struct called: ScrollBarInfo (as opposed to ScrollInfo) - and yet no functions seem to use this? What's it for?

If anyone has any ideas at all about how these scroll bars are being created - let me know!

A couple of points to remember:

I didn't create them, so they're not language specific (they must have been created (at some level) by Windows).
They do not have their own window, therefore there isn't a specific handle to them, just to the window that they are used by.
In an ideal world, i'd be able to call GetScrollInfo on them and get the page size. Or the min and max, or even just if they exist or not!
saltedAuthor Commented:
Hi TheLearnedOne,

Thanks for your help, unfortunately none of the windows below (and including) the part you've labeled as "Google - Microsoft Internet Explorer" (which is "IEFrame") has the style "WS_VSCROLL".

And I can't automate IE by interfacing IHTMLDocument(2), because only IE supports that, (and FF with a little work :) I need a general way of getting scroll bar info from a window by it's handle.
saltedAuthor Commented:
OK, one more thing I've noticed.

After a call to GetScrollInfo on a window within firefox, firefox stops repainting it's scroll bars until you resize the window... So if it's behind another window, you get a section of the overlapping window instead of the repainted scroll bar.

So it's doing something... but what?
Bob LearnedCommented:
I have no idea.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.