如何用C#触发TradingView的Alt+G打开日期跳转对话框?
问题:TradingView页面无法触发Alt+G快捷键调出日期跳转对话框
我用C#编写了ChromeWrapper类,目标是打开TradingView页面后触发Alt+G快捷键调出日期跳转对话框。参考相关线程新增SendAltKey方法后,在Stack Overflow页面测试Tab、Enter等普通按键有效,但在TradingView中调用SendAltKey('G')和SendKeys.Send("%G")均无效,且页面无日期相关查询参数,求可行解决方案。
调用代码
ChromeWrapper chrome = new ChromeWrapper(@"https://stackoverflow.com"); Thread.Sleep(1000); chrome.SendKey((char)9);// tab chrome.SendKey((char)13);//enter // 打开TradingView并调出日期跳转对话框,目前卡在这一步 chrome = new ChromeWrapper(@"https://www.tradingview.com/chart/?symbol=NASDAQ%3AMSFT"); Thread.Sleep(10000); chrome.SendAltKey('G'); // 无效 SendKeys.Send("%G"); // 同样无效
ChromeWrapper类代码
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Meh { public class ChromeWrapper { [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); private static uint WM_KEYDOWN = 0x100, WM_KEYUP = 0x101; public Process chromeProcess; public ChromeWrapper(string url) { chromeProcess = new Process(); chromeProcess.StartInfo = new ProcessStartInfo("chrome.exe", url); chromeProcess.StartInfo.UseShellExecute = true; chromeProcess.Start(); Thread.Sleep(600); Process[] procsChrome = Process.GetProcessesByName("chrome"); foreach (Process chrome in procsChrome) { if (chrome.MainWindowHandle == IntPtr.Zero) continue; chromeProcess = chrome; return; } } public void SendKey(char key) { try { if (chromeProcess.MainWindowHandle != IntPtr.Zero) { SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYDOWN, (IntPtr)key, IntPtr.Zero); Thread.Sleep(30); SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYUP, (IntPtr)key, IntPtr.Zero); } } catch (Exception e) { } } public void SendAltKey(char key) { try { if (chromeProcess.MainWindowHandle != IntPtr.Zero) { uint lparam = (0x01 << 28); SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYDOWN, (IntPtr)key, (IntPtr) lparam); Thread.Sleep(30); SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYUP, (IntPtr)key, (IntPtr) lparam); } } catch (Exception e) { } } } }
解决方案
1. 改用SendInput模拟硬件级按键(推荐)
SendMessage是直接向顶层窗口发送消息,而TradingView这类现代网页应用的快捷键监听在浏览器渲染进程中,并非顶层窗口。改用SendInput模拟真实用户的硬件按键操作,兼容性更强:
首先在ChromeWrapper类中添加必要的结构体和DllImport:
[StructLayout(LayoutKind.Sequential)] private struct INPUT { public uint Type; public KEYBDINPUT Ki; } [StructLayout(LayoutKind.Sequential)] private struct KEYBDINPUT { public ushort Vk; public ushort Scan; public uint Flags; public uint Time; public IntPtr ExtraInfo; } [DllImport("user32.dll", SetLastError = true)] private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); [DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); private const uint INPUT_KEYBOARD = 1; private const uint KEYEVENTF_KEYUP = 0x0002; private const ushort VK_MENU = 0x12; // Alt键虚拟键码
然后添加模拟Alt+G的方法:
public void SendAltGSimulated() { if (chromeProcess.MainWindowHandle == IntPtr.Zero) return; // 先激活Chrome窗口,确保按键被正确接收 SetForegroundWindow(chromeProcess.MainWindowHandle); Thread.Sleep(100); INPUT[] inputs = new INPUT[4]; // 按下Alt inputs[0].Type = INPUT_KEYBOARD; inputs[0].Ki.Vk = VK_MENU; inputs[0].Ki.Scan = 0; inputs[0].Ki.Flags = 0; // 按下G inputs[1].Type = INPUT_KEYBOARD; inputs[1].Ki.Vk = (ushort)'G'; inputs[1].Ki.Scan = 0; inputs[1].Ki.Flags = 0; // 松开G inputs[2].Type = INPUT_KEYBOARD; inputs[2].Ki.Vk = (ushort)'G'; inputs[2].Ki.Scan = 0; inputs[2].Ki.Flags = KEYEVENTF_KEYUP; // 松开Alt inputs[3].Type = INPUT_KEYBOARD; inputs[3].Ki.Vk = VK_MENU; inputs[3].Ki.Scan = 0; inputs[3].Ki.Flags = KEYEVENTF_KEYUP; SendInput(4, inputs, Marshal.SizeOf(typeof(INPUT))); }
2. 确保焦点在TradingView图表区域
TradingView的Alt+G快捷键需要焦点落在图表画布上,而非页面其他元素。可以先模拟鼠标点击图表中心位置(需结合SendInput模拟鼠标操作),再发送快捷键。
3. 替代方案:用Selenium直接操作前端DOM
如果模拟按键始终存在问题,改用Selenium WebDriver直接和TradingView的前端交互,稳定性更高:
- 安装Selenium ChromeDriver依赖
- 直接调用TradingView的JavaScript API触发日期跳转
示例代码:
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; var driver = new ChromeDriver(); driver.Navigate().GoToUrl("https://www.tradingview.com/chart/?symbol=NASDAQ%3AMSFT"); Thread.Sleep(10000); // 调用TradingView内置API调出日期跳转对话框 driver.ExecuteScript("chart.executeActionById('symbolSearch.gotoDate')"); // 后续可继续输入日期并确认
内容的提问来源于stack exchange,提问作者SeanK
相关产品推荐
相关产品推荐

