• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3865
  • Last Modified:

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.            
0
salted
Asked:
salted
  • 7
  • 4
  • 2
1 Solution
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
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");

        }
0
 
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.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
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.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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


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

But i also tested every window from the parent 'IEFrame' down.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
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...
0
 
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.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
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.???????????????????????);
        }
0
 
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 (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
0
 
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:

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!
0
 
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.
0
 
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?
0
 
Bob LearnedCommented:
I have no idea.

Bob
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now