Laden...

SHDocVW / MSHTML : Scrollbar-Position und Borderwidth abfragen ?

Erstellt von Lynix vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.592 Views
L
Lynix Themenstarter:in
667 Beiträge seit 2004
vor 12 Jahren
SHDocVW / MSHTML : Scrollbar-Position und Borderwidth abfragen ?

Hallo zusammen,

Ich nutze SHDocVW.dll und mshtml.dll um eine InternetExplorer Anwendung zu automatisieren. Soweit klappt es ganz gut, aber ich habe zwei Probleme, die mich in den Wahnsinn treiben, weil ich keine Dokumentation dazu finde.

Zum Einen brauche ich den aktuellen Ausschlag (integer-Wert) der Scrollbars (horizontal u. vertikal) eines Internet Explorer-Tabs, wobei der Tab vom Typ SHDocVW.IWebBrowser2 bzw. SHDocVW.InternetExplorer ist. Über beide Typen finde ich keine Möglichkeit, die Scrollbars auszulesen. Gibt es vielleicht ein weiteres Interface, in das ich das Tab-Objekt casten kann, welches mir dann den Zugriff auf die Scrollbars erlaubt ? Ich finde dazu nichts in der SHDocVW Referenz...

Das zweite Problem ist, dass ich beim Berechnen der globalen Desktop-Position eines Webcontrols im automatisierten HTML-Dokument immer einen Versatz von 3 Pixeln in x- und y-Richtung habe. Ich vermute, dass es sich dabei um die Borderwidth des Tabs handelt. Auch diesen müsste ich also irgendwie auslesen können, da ich nur ungern hartcodiert immer +3 rechnen möchte.

Ich hoffe, es hat schonmal jemand mit SHDocVW und MSHTML gearbeitet und kann mir irgendwie weiter helfen.

Die .NET internen Internetexplorer Controls kann ich leider nicht nutzen, da mein Tool imstande sein muss, sich mit einer externen Internetexplorer-Instanz zu verbinden.

Danke...

Edit: Tippfehler beseitigt.

"It is not wise to be wise" - Sun Tzu

L
Lynix Themenstarter:in
667 Beiträge seit 2004
vor 12 Jahren

Die scrollbar-Problematik konnte ich gerade lösen.

Wen es interessiert: Wenn browser die SHDocVW.InternetExplorer Instanz ist, kriegt man die Scrollbar-Werte so:


HTMLDocument doc = (HTMLDocument)browser.Document;
HTMLHtmlElement html = (HTMLHtmlElement)doc.DocumentElement;
int scrollX = html.scrollLeft;
int scrollY = html.scrollTop;

Die Scrollbarwerte kommen dabei in falscher (negativer) Richtung zurück, d.h. man muss die Scrollbarwerte von der Koordinate abziehen anstatt sie zu addieren.

Für den Border hab ich immer noch nichts gefunden...

"It is not wise to be wise" - Sun Tzu

W
56 Beiträge seit 2009
vor 12 Jahren

Zum Border, wenn du dir die GUI/Window-Struktur des InternetExplorers in WinSpector anschaust, dann findest du folgendes herraus, es gibt ein IEFrame, welches viele Internet Explorer_Server beinhaltet. Das IEFrame ist alles ausserhalb des HTMLDokuments. Du kannst jetzt also so vorgehen,
du benutzt die Win32.dll und suchst nach dem IEFrame Window, holst dir die Maße des Windows. Dann suchst nach deinem Internet Explorer_Server Window und holst dir dessen Maße. Du ziehst nun die beiden voneinander ab, und hast so die Border Werte.

Werde heute evtl. noch einen fertigen Code posten, je nach Zeit. 😉

mfg Iwan

Alle haben gesagt es geht nicht, dann kam einer der hat das nicht gehört und hat es gemacht.

W
56 Beiträge seit 2009
vor 12 Jahren

Sorry für den Doppelpost,

Hier holen wir uns erstmal das Window handle für unseren Tab.

 
[ComImport]
[Guid("00000114-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleWindow
{
    void GetWindow(out IntPtr phwnd);
    void ContextSensitiveHelp([In, MarshalAs(UnmanagedType.Bool)] bool fEnterMode);
}
       
private IntPtr _GetHwnd(IWebBrowser2 _browser)
{
     IOleWindow window = null;
     try
     {
        window = _browser.Document as IOleWindow;
        if (window == null)
           return IntPtr.Zero;

        return _GetWindowHandle(window);
    }
    catch
    {
        return IntPtr.Zero;
    }
}

private IntPtr _GetWindowHandle(IOleWindow window)
{
   IntPtr handle = IntPtr.Zero;
   window.GetWindow(out handle);
   return handle;
}

Jetzt benötigen wir noch das Handle des IEFrames, was schon direkt im IWebBrowser2 Objekt abrufbar ist:

private IntPtr GetIEFrame(IWebBrowser2 _browser)
{
   return (IntPtr)_browser.HWND;
}

Dann holen wir uns noch die Maße der Windows, wobei wir hier einen neuen von der Win32.dll vorgegebenen Datentypen hinzufügen müssen.

[DllImport("user32.dll", SetLastError = true)]
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); 

[StructLayout(LayoutKind.Sequential)]
public struct RECT 
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

private RECT GetSize(IntPtr hwnd)
{
    RECT tmp;
    GetWindowRect(hwnd, out tmp);
    return tmp;
}

Das rechnen überlass ich dir. 😃

MfG Iwan

Alle haben gesagt es geht nicht, dann kam einer der hat das nicht gehört und hat es gemacht.