salted
asked on
Call to "GetScrollInfo" Win API with C#
Hi,
Anyone know why this call to GetScrollInfo returns false?
[StructLayout(LayoutKind.S equential) ]
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.
Anyone know why this call to GetScrollInfo returns false?
[StructLayout(LayoutKind.S
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(
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.
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.
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.
"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,
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.
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?
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?
ASKER
Sorry, I meant "... even 'Internet Explorer_Server' doesn't do it...."
But i also tested every window from the parent 'IEFrame' down.
But i also tested every window from the parent 'IEFrame' down.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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 _DocumentC ompleteEve ntHandler( IE_Documen tComplete) ;
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.Doc ument);
Debug.Print(html.parentWin dow.?????? ?????????? ???????);
}
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
IE.Visible = true;
Object o = null;
IE.Navigate("http://www.google.com", ref o, ref o, ref o, ref o);
}
void IE_DocumentComplete(object
{
HTMLDocumentClass html = (HTMLDocumentClass)(IE.Doc
Debug.Print(html.parentWin
}
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
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
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!
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!
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.
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.
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?
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
Bob
[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.InteropServ
si.fMask = SIF_ALL;
GetScrollInfo(this.Handle,
MessageBox.Show("nPage: " + si.nPage.ToString() + "\n\n"
+ "nPos: " + si.nPos.ToString() + "\n\n" +
"nMax: " + si.nMax.ToString() + "\n\n");
}