我一直在寻找,我还没有找到如何从C#中做到这一点。
我想要这样做,所以我可以告诉谷歌浏览器转发,返回,打开新标签,关闭选项卡,打开新窗口,以及来自我的C#应用程序的关闭窗口。
我使用
做了与WinAmp类似的事情[DllImport("user32", EntryPoint = "SendMessageA")]
private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);
和其他一些人。但我不知道要发送什么消息或者如何找到传递给它的窗口,或者其他什么。
那么有人可以告诉我如何从C#向Chrome发送这6个命令吗?感谢
编辑: 好吧,我正在投票,所以也许我不够清楚,或者人们假设我没有试图自己解决这个问题。
首先,我对整个DllImport的东西不太满意。我还在学习它是如何运作的。
我几年前在winamp找到了如何做同样的想法,我正在查看我的代码。我做了所以我可以跳过一首歌,回去,播放,暂停,并停止从我的C#代码winamp。我开始导入:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow([MarshalAs(UnmanagedType.LPTStr)] string lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SendMessageA(IntPtr hwnd, int wMsg, int wParam, uint lParam);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetWindowText(IntPtr hwnd, string lpString, int cch);
[DllImport("user32", EntryPoint = "FindWindowExA")]
private static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);
[DllImport("user32", EntryPoint = "SendMessageA")]
private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam);
然后我发现使用它的代码将这些常量用于我发送的消息。
const int WM_COMMAND = 0x111;
const int WA_NOTHING = 0;
const int WA_PREVTRACK = 40044;
const int WA_PLAY = 40045;
const int WA_PAUSE = 40046;
const int WA_STOP = 40047;
const int WA_NEXTTRACK = 40048;
const int WA_VOLUMEUP = 40058;
const int WA_VOLUMEDOWN = 40059;
const int WINAMP_FFWD5S = 40060;
const int WINAMP_REW5S = 40061;
我会通过以下方式获取 hwnd (发送消息的程序):
IntPtr hwnd = FindWindow(m_windowName, null);
然后我会向该程序发送一条消息:
SendMessageA(hwnd, WM_COMMAND, WA_STOP, WA_NOTHING);
我认为我会为Google Chrome做一些非常类似的事情。但是我不知道这些价值观应该是什么,我用Google搜索找到答案,但我不能,这就是我在这里问的原因。所以我的问题是我如何得到以下值:
m_windowName 和 WM_COMMAND
然后,不同命令的值,转发,返回,新标签,关闭标签 ,新窗口,关闭窗口?
答案 0 :(得分:9)
在http://dev.chromium.org/developers
开始您的研究编辑:向窗口发送消息只是工作的一半。窗口必须响应该消息并相应地采取行动。如果该窗口不知道某条消息或根本不关心,则您无法通过发送窗口消息来控制它。
您正在查看有关如何远程控制Winamp的实现细节。发送消息只是实现它的一种方式,而这正是Winamp开发人员选择的方式。您正在使用的那些消息是用户定义的消息,它们具有仅到Winamp的特定含义。
在第一步中您需要做的是找出如果 Chromium支持某种远程控制以及这些机制是什么。
答案 1 :(得分:7)
您可以使用Visual Studio的Spy ++轻松获取窗口名称,然后按CTRL + F,然后找到chrome。我试过了,然后
out窗口的“Chrome_VistaFrame”。网页的实际窗口为“Chrome_RenderWidgetHostHWND”。
就WM_COMMAND而言 - 你需要进行实验。你显然想要发送按钮点击(我头顶的WM_MOUSEDOWN)。由于后退,前进按钮不是他们自己的窗口,你需要弄清楚如何通过在某个x,y位置模拟鼠标点击来实现这一点,以便Chrome知道你正在做什么。或者您可以发送等效于后退/前进的键盘快捷键等等。
我刚才写的一个例子是用trillian和winamp做的:sending messages to windows via c# and winapi
还有一些工具可以使用脚本语言将这种事情宏观化 - autoit是我用过的:autoit.com
答案 2 :(得分:4)
好的,这就是我到目前为止所得到的...我知道我需要做什么,但这只是现在做的事情......
这是Spy ++的窗口,我锁定了 Chrome_RenderWidgetHostHWND ,然后点击键盘上的“后退”按钮。这是我得到的:
所以这是我的假设,现在我一直在玩这个,我只是想不出值。
IntPtr hWnd = FindWindow("Chrome_RenderWidgetHostHWND", null);
SendMessage(hWnd, WM_KEYDOWN, VK_BROWSER_BACK, 0);
SendMessage(hWnd, WM_KEYUP, VK_BROWSER_BACK, 0);
现在,我只是不知道我应该制作WM_KEYDOWN / UP值或VK_BROWSER_BACK / FORWARD值... 我试过这个:
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int VK_BROWSER_BACK = 0x6A;
const int VK_BROWSER_FORWARD = 0x69;
我从刚刚显示的图像中得到的后两个值,这两个键的ScanCodes。我不知道我是否做得对。我在搜索谷歌获取WM_KEYDOWN值后得到的前两个值,有人使用& H100和& H101作为这两个值。我已经尝试了其他一些我见过的随机想法。我只是想不出来。
哦,这是SendMessage方法
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, uint lParam);
答案 3 :(得分:4)
这是互操作常量的绝佳站点:
查找值的另一种方法是使用C#作为语言搜索koders.com,WM_KEYDOWN或您之后的常量:
& H值看起来像是VB(6)。 pinvoke和koders都返回VK_BROWSER_FORWARD的结果,
private const UInt32 WM_KEYDOWN = 0x0100;
private const UInt32 WM_KEYUP = 0x0101;
public const ushort VK_BROWSER_BACK = 0xA6;
public const ushort VK_BROWSER_FORWARD = 0xA7;
public const ushort VK_BROWSER_REFRESH = 0xA8;
public const ushort VK_BROWSER_STOP = 0xA9;
public const ushort VK_BROWSER_SEARCH = 0xAA;
public const ushort VK_BROWSER_FAVORITES = 0xAB;
public const ushort VK_BROWSER_HOME = 0xAC;
(有趣的是,有多少错误的VK常量定义正在浮动,考虑到VK_ *是1字节0-255的值,并且人们已经使它们变得不正常了。)
与您的视频略有不同。我认为你所追求的功能是SendInput(但我还没试过),因为它是一个虚拟键。
[DllImport("User32.dll")]
private static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] KEYBOARD_INPUT[] input, int structSize);
有关参数的说明:
参数
这需要KEYBOARD_INPUT类型:
[StructLayout(LayoutKind.Sequential)]
public struct KEYBOARD_INPUT
{
public uint type;
public ushort vk;
public ushort scanCode;
public uint flags;
public uint time;
public uint extrainfo;
public uint padding1;
public uint padding2;
}
最后是一个样本,我没有测试它是否有效:
/*
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
*/
public static void sendKey(int scanCode, bool press)
{
KEYBOARD_INPUT[] input = new KEYBOARD_INPUT[1];
input[0] = new KEYBOARD_INPUT();
input[0].type = INPUT_KEYBOARD;
input[0].vk = VK_BROWSER_BACK;
uint result = SendInput(1, input, Marshal.SizeOf(input[0]));
}
此外,您还需要使用SetForegroundWindow
关注Chrome窗口