Pregunta

He estado buscando, y no he encontrado cómo haría esto desde C #.

Quería hacerlo para poder decirle a Google Chrome que vaya Adelante , Atrás , Abrir nueva pestaña , Cerrar Tabulación , Abrir nueva ventana y Cerrar ventana desde mi aplicación C #.

Hice algo similar con WinAmp usando

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

y algunos otros. Pero no sé qué mensaje enviar o cómo encontrar a qué ventana pasarlo, o algo así.

Entonces, ¿podría alguien mostrarme cómo enviaría esos 6 comandos a Chrome desde C #? gracias

EDITAR: Ok, me están rechazando, así que tal vez no fui lo suficientemente claro, o la gente está asumiendo que no traté de resolver esto por mi cuenta.

En primer lugar, no soy muy bueno con todo el contenido de DllImport. Todavía estoy aprendiendo cómo funciona todo.

Hace unos años descubrí cómo hacer la misma idea en winamp, y estaba mirando mi código. Lo hice para poder omitir una canción, regresar, reproducir, pausar y detener winamp de mi código C #. Empecé importando:

    [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);

Luego, el código que encontré para usar esto usó estas constantes para los mensajes que envío.

    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;

Obtendría el hwnd (el programa al que enviar el mensaje):

IntPtr hwnd = FindWindow(m_windowName, null);

luego enviaría un mensaje a ese programa:

SendMessageA(hwnd, WM_COMMAND, WA_STOP, WA_NOTHING);

Supongo que haría algo muy similar a esto para Google Chrome. pero no sé cuáles deberían ser algunos de esos valores, y busqué en Google tratando de encontrar la respuesta, pero no pude, por eso pregunté aquí. Entonces mi pregunta es cómo obtengo los valores para:

m_windowName y WM_COMMAND

y luego, los valores para los diferentes comandos, adelante , atrás , nueva pestaña , cerrar pestaña , nueva ventana , cerrar ventana ?

¿Fue útil?

Solución

Comience su investigación en http://dev.chromium.org/developers


EDIT : enviar un mensaje a una ventana es solo la mitad del trabajo. La ventana tiene que responder a ese mensaje y actuar en consecuencia. Si esa ventana no conoce un mensaje o no le importa en absoluto, no tiene oportunidad de controlarlo mediante el envío de mensajes de la ventana.

Estás viendo un detalle de implementación sobre cómo controlas Winamp de forma remota. Enviar mensajes es solo una forma de hacerlo y es la forma en que los desarrolladores de Winamp eligieron. Los mensajes que está utilizando son mensajes definidos por el usuario que tienen un significado específico solo para Winamp.

Lo que debe hacer en el primer paso es averiguar si Chromium admite algún tipo de control remoto y cuáles son esos mecanismos.

Otros consejos

Puede obtener el nombre de la ventana fácilmente usando Spy ++ de Visual Studio y presionando CTRL + F, luego buscando Chrome. Lo probé y lo conseguí

" Chrome_VistaFrame " Por la ventana exterior. La ventana real con la página web es " Chrome_RenderWidgetHostHWND " ;.

En cuanto a WM_COMMAND, tendrás que experimentar. Obviamente querrás enviar clics de botón (WM_MOUSEDOWN de la parte superior de mi cabeza). Como los botones de retroceso y avance no son sus propias ventanas, deberá descubrir cómo hacer esto simulando un clic del mouse en una determinada posición x, y para que Chrome sepa lo que está haciendo. O puede enviar el método abreviado de teclado equivalente para atrás / adelante y así sucesivamente.

Un ejemplo que escribí hace un tiempo hace esto con trillian y winamp: enviando mensajes a windows a través de c # y winapi

También hay herramientas para macrosificar este tipo de cosas, usando un lenguaje de scripting; autoit es una que he usado: autoit.com

Ok, esto es lo que tengo hasta ahora ... Sé lo que necesito hacer, pero solo es cuestión de hacerlo ahora ...

Aquí está la ventana de Spy ++, me fijé en Chrome_RenderWidgetHostHWND y presioné el botón Atrás en mi teclado. Esto es lo que tengo: alt text

Aquí están mis suposiciones, y he estado jugando con esto desde siempre, simplemente no puedo entender los valores .

IntPtr hWnd = FindWindow("Chrome_RenderWidgetHostHWND", null);
SendMessage(hWnd, WM_KEYDOWN, VK_BROWSER_BACK, 0);
SendMessage(hWnd, WM_KEYUP,   VK_BROWSER_BACK, 0);

Ahora, simplemente no sé qué debo hacer con los valores WM_KEYDOWN / UP o los valores VK_BROWSER_BACK / FORWARD ... Intenté esto:

const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
const int VK_BROWSER_BACK = 0x6A;
const int VK_BROWSER_FORWARD = 0x69;

Los dos últimos valores que obtuve de la imagen que acabo de mostrar, los ScanCodes para esas dos teclas. Sin embargo, no sé si lo hice bien. Los dos primeros valores que obtuve después de buscar en Google el valor WM_KEYDOWN, y alguien usó & amp; H100 y & amp; H101 para los dos valores. He intentado varias otras ideas aleatorias que he visto flotando alrededor. Simplemente no puedo resolver esto.

Ah, y aquí está el método SendMessage

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

Este es un gran sitio para constantes de interoperabilidad:

pinvoke

Otra forma de encontrar los valores es buscar en koders.com, usando C # como idioma, para WM_KEYDOWN o la constante que buscas:

Búsqueda de Koders.com

Los valores de

y amp; H parecen que son de VB (6). pinvoke y koders devuelven resultados para 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;

(Es curioso la cantidad de definiciones erróneas de las constantes de VK que están flotando, considerando que VK_ * son valores de 1 byte 0-255, y las personas las han convertido en puntos).

Parece un poco diferente de tus concursos. Creo que la función que buscas es SendInput (pero no lo he probado) ya que es una clave virtual.

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

Explicación sobre los parámetros:

Parámetros

  • nInputs: número de estructuras en la matriz pInputs.
  • pInputs: puntero a una matriz de estructuras INPUT. Cada estructura representa un evento que se inserta en el flujo de entrada del teclado o del mouse.
  • cbSize: especifica el tamaño, en bytes, de una estructura INPUT. Si cbSize no es del tamaño de una estructura INPUT, la función falla.

Esto necesita un tipo 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; 
}

Y finalmente una muestra, que no he probado si funciona:

/*
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]));
}

También deberá enfocar la ventana de Chrome utilizando SetForegroundWindow

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top