Gon*_*ing 13
基本上我有太多的代码来分离出这个例子的最小值,但是我已经提供了下面的算法来让你倾注.
这个也会跟踪浏览器中的选项卡,当它们重新出现时(仅限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;
}
Run Code Online (Sandbox Code Playgroud)
如果Microsoft Spy ++可以看到地址控件,那么是的.
我没有安装Opera,但Spy ++中的Chrome控件层次结构如下所示:
我用Internet Explorer做过类似的事情:
Firefox是问题孩子,因为它在内部呈现地址栏而不是通过Windows控件,但我发现你已经找到了解决方案.
在C#中,您需要对Windows API方法进行非托管调用.正如您可以从单独的C#API代码(下面)中看到的那样,它可能会涉及到一些问题:
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;
}
Run Code Online (Sandbox Code Playgroud)
所涉及的算法基本上从桌面上搜索所有窗口,直到它找到浏览器窗口(基于特定的类或窗口属性).然后,它根据浏览器的类型搜索特定的子元素.当您最终到达地址控件时,您可以从控件中提取地址.希望我的助手类代码能加速你的开发.
该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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr parentHandle,
IntPtr childAfter, string className, IntPtr windowTitle);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd,
int msg, int wParam, StringBuilder ClassName);
private static string GetURL(IntPtr intPtr, string programName, out string url)
{
string temp=null;
if (programName.Equals("chrome"))
{
var hAddressBox = FindWindowEx(intPtr, IntPtr.Zero, "Chrome_OmniboxView", IntPtr.Zero);
var sb = new StringBuilder(256);
SendMessage(hAddressBox, 0x000D, (IntPtr)256, sb);
temp = sb.ToString();
}
if (programName.Equals("iexplore"))
{
foreach (InternetExplorer ie in new ShellWindows())
{
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(ie.FullName);
if (fileNameWithoutExtension != null)
{
var filename = fileNameWithoutExtension.ToLower();
if (filename.Equals("iexplore"))
{
temp+=ie.LocationURL + " ";
}
}
}
}
if (programName.Equals("firefox"))
{
DdeClient dde = new DdeClient("Firefox", "WWW_GetWindowInfo");
dde.Connect();
string url1 = dde.Request("URL", int.MaxValue);
dde.Disconnect();
temp = url1.Replace("\"","").Replace("\0","");
}
url = temp;
return temp;
}
Run Code Online (Sandbox Code Playgroud)
请执行以下操作以在您的项目中从 VS.NET 添加参考 > Com > Microsoft.Internet.Controls
从http://ndde.codeplex.com/下载DdeClient 类的 bin并将其添加到您的项目中
归档时间: |
|
查看次数: |
24262 次 |
最近记录: |