Link to home
Start Free TrialLog in
Avatar of salted
salted

asked on

Call to "GetScrollInfo" Win API with C#

Hi,

Anyone know why this call to GetScrollInfo returns false?

        [StructLayout(LayoutKind.Sequential)]
        public struct SCROLLINFO
        {
            public int cbSize;
            public int fMask;
            public int nMin;
            public int nMax;
            public int nPage;
            public int nPos;
            public int nTrackPos;
        }

...

        [DllImport("user32.dll")]
        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.            
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Try...

        [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");

        }
Avatar of salted
salted

ASKER

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.
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.
Avatar of salted

ASKER

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:
WS_CHILDWINDOW
WS_VISIBLE
WS_CLIPSIBLINGS
WS_CLIPCHILDREN


Any ideas?
Avatar of salted

ASKER

Sorry, I meant "... even 'Internet Explorer_Server' doesn't do it...."

But i also tested every window from the parent 'IEFrame' down.
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of salted

ASKER

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.
This is definitely NOT my forte!    =\

It may be possible to get the scrollbar info from IE via automation:
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/properties/scrolltop.asp

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("http://www.google.com", ref o, ref o, ref o, ref o);
        }

        void IE_DocumentComplete(object pDisp, ref object URL)
        {
            HTMLDocumentClass html = (HTMLDocumentClass)(IE.Document);
            Debug.Print(html.parentWindow.???????????????????????);
        }
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 (http://www.google.com):

Google - Microsoft Internet Explorer
  WorkerW
  ReBarWindow32
  ComboBoxEx32
  ToolbarWindow32
  ComboBox
  Edit
  ToolbarWindow32
  ToolbarWindow32
  WorkerW
  ToolbarWindow32
  WorkerW
  msctls_statusbar32
  msctls_progress32
  Shell DocObject View
  Internet Explorer_Server

Bob
Avatar of salted

ASKER

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:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/scrollbars/aboutscrollbars.asp

"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!
Avatar of salted

ASKER

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.
Avatar of salted

ASKER

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?
I have no idea.

Bob