Часть 2:
По сути, у меня слишком много кода, чтобы выделить минимум для этого примера, но ниже я предоставил свой собственный алгоритм для вас, чтобы использовать его.
Этот файл также отслеживает вкладки в браузерах по мере их появления (только для IE), поэтому вам придется удалять ненужные фрагменты.Кажется, я помню, что исправил это для IE8, но не уверен, что это исправление вошло в этот код, так что не удивляйтесь, если он нуждается в небольшой настройке:)
// Iterate all browsers and record the details
IntPtr hWnd = IntPtr.Zero;
NativeWIN32.EnumChildWindows(hWnd, new NativeWIN32.Win32Callback(BrowserEnumCallback), hWnd);
/// <summary>
/// Called back for each IE browser.
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
static bool BrowserEnumCallback(IntPtr hWnd, IntPtr lParam)
{
// Is this app IE?
if (NativeWIN32.GetClassName(hWnd) == "IEFrame")
{
// If this is a new browser, add it
if (!BrowserWindows.ContainsKey(hWnd))
{
// Record the Browser
BrowserWindow browser = new BrowserWindow()
{
hWnd = hWnd
};
// Store the browser in the temp list and temp member
TempCurrentBrowser = browser;
BrowserWindows.Add(hWnd, browser);
}
else
{
// Store the browser in the temp list and temp member
TempCurrentBrowser = BrowserWindows[hWnd];
}
TempCurrentBrowser.WindowText = NativeWIN32.GetWindowText(hWnd);
TempCurrentBrowser.Found = true;
// Now that we know it is a browser, look for tabbed windows and address bar
NativeWIN32.EnumChildWindows(hWnd, new NativeWIN32.Win32Callback(BrowserEnumChildrenCallback), hWnd);
}
return true;
}
/// <summary>
/// Called back for each child window in the browser
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
static bool BrowserEnumChildrenCallback(IntPtr hWnd, IntPtr lParam)
{
string classname = NativeWIN32.GetClassName(hWnd);
switch (classname)
{
// This is the main address bar
case "Edit":
{
string url = NativeWIN32.GetWindowText(hWnd);
if (url.StartsWith(@"http://") || url.StartsWith(@"https://") || url.StartsWith("about:"))
{
TempCurrentBrowser.Url = url;
return true;
}
}
break;
case "ComboBoxEx32":
{
string url = NativeWIN32.GetWindowText(hWnd);
if (url.StartsWith(@"http://") || url.StartsWith(@"https://") || url.StartsWith("about:"))
{
TempCurrentBrowser.Url = url;
return true;
}
}
break;
// Record any sub pages still active, by title to avoid revisiting popup
// If this name matches the name of the browser, it is the current window
// If so, record the browser url for reference in that tab window
case "TabWindowClass":
{
string title = NativeWIN32.GetWindowText(hWnd);
BrowserTabWindow tabWindow;
if (!TempCurrentBrowser.TabWindows.ContainsKey(hWnd))
{
// Create a new tabbed window for the current browser
tabWindow = new BrowserTabWindow()
{
hWnd = hWnd
};
TempCurrentBrowser.TabWindows.Add(hWnd, tabWindow);
}
else
{
tabWindow = TempCurrentBrowser.TabWindows[hWnd];
}
tabWindow.WindowText = title;
tabWindow.Found = true;
}
break;
}
return true;
}
Часть 1:
Если Microsoft Spy ++ может видеть управление адресами, тогда да, это возможно.
У меня не установлена Opera, но иерархия управления Chrome в Spy ++ выглядит следующим образом:
![alt text](https://i.stack.imgur.com/HlmTm.png)
Я сделал аналогичные вещи с Internet Explorer:
- Чтобы записать дневник посещенных сайтов - тогда всплывающее окно спросит пользователя, что они делают
- Чтобы отобразить виджет, который появляется при посещении определенных известных сайтов
Firefox был проблемным потомком , поскольку он отображает адресную строку внутри, а не через элемент управления Windows, но я вижу васМы уже нашли решение этой проблемы.
В C # вам необходимо совершать неуправляемые вызовы методов Windows API.Как видно из одного только кода API C # (ниже), он может быть немного сложным:
const int WM_GETTEXT = 0xD;
// used for an output LPCTSTR parameter on a method call
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct STRINGBUFFER
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string szText;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parent /*HWND*/,
IntPtr next /*HWND*/,
string sClassName,
IntPtr sWindowTitle);
/// <summary>
///
/// </summary>
/// <param name="hWnd">handle to destination window</param>
/// <param name="msg">message</param>
/// <param name="wParam">first message parameter</param>
/// <param name="lParam"second message parameter></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd,
int msg, int wParam, out STRINGBUFFER ClassName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);
//[DllImport("user32.dll")]
//[return: MarshalAs(UnmanagedType.Bool)]
//static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
/// <summary>
/// Helper to get window classname
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
static public string GetClassName(IntPtr hWnd)
{
NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
NativeWIN32.GetClassName(hWnd, out sLimitedLengthWindowTitle, 256);
return sLimitedLengthWindowTitle.szText;
}
/// <summary>
/// Helper to get window text
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
static public string GetWindowText(IntPtr hWnd)
{
NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
SendMessage(hWnd, WM_GETTEXT, 256, out sLimitedLengthWindowTitle);
//NativeWIN32.GetWindowText(hWnd, out sLimitedLengthWindowTitle, 256);
return sLimitedLengthWindowTitle.szText;
}
Используемый алгоритм в основном ищет все окна с рабочего стола и далее, пока не найдет Browser окна (на основе определенного класса или атрибутов окна).Затем он ищет конкретные дочерние элементы в зависимости от типа браузера.Когда вы наконец доберетесь до элемента управления адресами, вы можете извлечь адрес из элемента управления.Надеюсь, мой код класса помощника ускорит вашу разработку.
Продолжение "NativeWIN32" - декабрь 2013
Ссылки NativeWIN32
- это просто класс-оболочка, содержащий полезные константы и методы для других функций Win32.Я добавил это здесь полностью:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace YourProject
{
/// <summary>
/// Wrapper for native win32 calls
/// </summary>
public class NativeWIN32
{
const int WM_GETTEXT = 0xD;
// used for an output LPCTSTR parameter on a method call
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct STRINGBUFFER
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string szText;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parent /*HWND*/,
IntPtr next /*HWND*/,
string sClassName,
IntPtr sWindowTitle);
/// <summary>
///
/// </summary>
/// <param name="hWnd">handle to destination window</param>
/// <param name="msg">message</param>
/// <param name="wParam">first message parameter</param>
/// <param name="lParam"second message parameter></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd,
int msg, int wParam, out STRINGBUFFER ClassName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);
//[DllImport("user32.dll")]
//[return: MarshalAs(UnmanagedType.Bool)]
//static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
/// <summary>
/// Helper to get window classname
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
static public string GetClassName(IntPtr hWnd)
{
NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
NativeWIN32.GetClassName(hWnd, out sLimitedLengthWindowTitle, 256);
return sLimitedLengthWindowTitle.szText;
}
/// <summary>
/// Helper to get window text
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
static public string GetWindowText(IntPtr hWnd)
{
NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
SendMessage(hWnd, WM_GETTEXT, 256, out sLimitedLengthWindowTitle);
//NativeWIN32.GetWindowText(hWnd, out sLimitedLengthWindowTitle, 256);
return sLimitedLengthWindowTitle.szText;
}
}
}