2008-09-29 188 views
19

我一直在四处寻找,而我还没有找到如何从C#做到这一点。C# - 从C#应用程序发送消息给谷歌浏览器

我想使,所以我可以告诉谷歌Chrome浏览器去正向返回打开新Tab关闭标签打开新窗口,并从关闭窗口我C#应用程序。

我没有使用

[DllImport("user32", EntryPoint = "SendMessageA")] 
private static extern int SendMessage(int Hwnd, int wMsg, int wParam, int lParam); 

和别人几与Winamp的类似的东西。但我不知道要发送什么消息或如何找到将窗口传递给哪个窗口或任何其他窗口。

所以有人会告诉我如何将这6条命令从C#发送到Chrome?谢谢

编辑: 好吧,我被拒绝了,所以也许我不够清楚,或者人们假设我没有试图自己弄清楚这一点。

首先,我对整个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做一些与此类似的事情。但我不知道这些价值观应该是什么,我一直在寻找答案,但我不能,这就是我在这里问的原因。所以我的问题是如何得到的值:

m_windowNameWM_COMMAND

,然后为不同的命令值,向前,新标签close tab新窗口关闭窗口

回答

9

http://dev.chromium.org/developers


编辑开始你的研究:发送消息到一个窗口只是工作的一半。该窗口必须对该消息作出回应并采取相应措施。如果该窗口不知道消息或根本不关心,则无法通过发送窗口消息来控制消息。

您正在查看有关如何远程控制Winamp的实现细节。发送消息只是一种方法,Winamp开发人员选择这种方式。您使用的这些消息是用户定义的消息,其具有特定的含义只有 Winamp。

你需要做的第一步是找出如果铬支持某种遥控器以及这些机制是什么。

+0

我正在翻阅,我没有看到任何能够帮助我完成我想要做的事情。我不想重新编译Chrome或任何东西。我希望能够向Chrome发送一条消息,说“回头”或其他什么。我根本不想改变Chrome。从C#做这一切# – Joel 2008-09-29 08:57:55

7

您可以使用Visual Studio的Spy ++轻松获取窗口名称,然后按CTRL + F,然后查找chrome。我试了一下,得到了

“Chrome_VistaFrame”用于出窗口。网页的实际窗口是“Chrome_RenderWidgetHostHWND”。

就WM_COMMAND而言 - 您需要进行试验。你显然想发送按钮点击(WM_MOUSEDOWN顶部我的头)。作为后面,前进按钮不是他们自己的窗口,你需要弄清楚如何在某个x,y位置模拟鼠标点击来做到这一点,这样chrome就知道你在做什么。或者,您可以发送相应的后退/前进键盘快捷键等。

我写了,而以前这是否与翠莲和Winamp的一个例子:sending messages to windows via c# and winapi

还有工具,有宏观出这种事情已经使用一种脚本语言 - AutoIt的是一个我用: autoit.com

+0

所以我一直玩这个一个小时或两个小时。 我想发送键盘快捷键。现在我想弄清楚如何发送Chrome的消息WM_KEYDOWN和WM_KEYUP的VK_BROWSER_BACK键。但我无法弄清楚他们的int值。 – Joel 2008-09-29 18:18:25

4

好吧,这里就是我这么远......我有点知道我需要做的,但它只是一个做,现在的事情......

下面是来自间谍窗口++,我锁定到Chrome_RenderWidgetHostHWND并单击我的键盘上的后退按钮。下面是我的了: alt text

因此,这里是我的假设,我已经永远现在玩这个,我只是想不通的。现在

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。我不知道我是否做得对。前两个值是在google搜索WM_KEYDOWN值后得到的,另外有人使用了& H100和& H101作为这两个值。我尝试了几个我见过的随机创意。我无法弄清楚这一点。

哦,这里的SendMessage函数方法

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
    static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, uint lParam); 
4

这是互操作常量一个伟大的网站:

pinvoke

寻找价值的另一种方式是搜索koders.com,使用C#作为语言,用于WM_KEYDOWN或常用于之后:

Koders.com search

& 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常量的很多错误defintions浮动一下,考虑VK_ *为1个字节0-255价值观和人民作出了他们的uint)。

与你的常量略有不同。我认为你之后的函数是SendInput(但我没有尝试过),因为它是一个虚拟键。

[DllImport("User32.dll")] 
private static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] KEYBOARD_INPUT[] input, int structSize); 

说明有关参数:

参数

  • nInputs-的pInputs阵列中的结构的数目。
  • pInputs - 指向INPUT结构数组的指针。每个结构表示要插入到键盘或鼠标输入流中的事件。
  • cbSize - 指定INPUT结构的大小(以字节为单位)。如果cbSize不是INPUT结构的大小,则该函数失败。

这需要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])); 
} 

而且你需要关注的Chrome窗口使用SetForegroundWindow

相关问题