有什么方法可以在键盘上发布笔画序列吗?
使用下面的SendInput代码在我的计算机上运行得非常好并且自信,但是当我在其他人(使用相同或其他操作系统(W7 / W10))上进行测试时,它没有。 当我尝试检查返回代码和上次错误时,我在各处都获得了成功(发布了X键击,返回代码:0),但没有完成笔画。
我的程序差不多完成了,早些时候有人建议我使用UIAutomation,但我现在对这项技术并不熟悉,我认为完全重新完成整个代码是无稽之谈。
任何人都可以告诉我有关winapi或C#类的信息,它可以替代SendInput并可靠地完成工作,或者我的代码中的内容很糟糕,而在我的机器上运行良好而在其他机器上运行不好。
非常感谢
PIXEL_COLOR pix = PIXEL_COLOR.PIX_UNKNOWN;
bool isException = false;
string mess ="";
uint a = 0, b = 0;
int ea = -1, eb = -1;
try
{
const int TRUE = 1;
const int FALSE = 0;
MainWindow.ShowWindow(GetParent(clickSettings.GetHandler), SW_SHOWMAXIMIZED);
SetWindowPos(GetParent(clickSettings.GetHandler), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
switch (lev.expiry)
{
case 5:
case 10:
case 15:
PutSingleClick(clickSettings.GetHandler, clickSettings.GetM15.GetX, clickSettings.GetM15.GetY);
break;
case 60:
PutSingleClick(clickSettings.GetHandler, clickSettings.GetM60.GetX, clickSettings.GetM60.GetY);
break;
}
//show list
PutSingleClick(clickSettings.GetHandler, clickSettings.GetInstruments.GetX, clickSettings.GetInstruments.GetY);
Thread.Sleep(1000);
//downarrows
a = PutKeystroke(hWndMain, (int)lev.symbol, TRUE, out ea);
Thread.Sleep(1000);
有两个鼠标点击,第二个是浏览器的组合框,我需要“手动”(通过键盘)选择一个项目。它使用以下代码从库中执行本机winapi函数:
extern "C" __declspec(dllexport) UINT __stdcall PutKeystroke(HWND hnd, int index, BOOL isDown, int& err)
{
INPUT ip = {0};
ip.type = INPUT_KEYBOARD;
ip.ki.wVk =isDown? VK_DOWN : VK_UP;
int times;
if(index < 2)
times = index+1;
else
times = index+2; //only correction, I forgot an option on third position which is not needed (and I'm very lazy :)
INPUT ips[100] = {0};
for(int i = 0; i < times*2; i+=2)
{
ip.ki.dwFlags = 0;
ips[i] = ip;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
ips[i+1] = ip;
}
ip.ki.dwFlags = 0;
ip.ki.wVk = VK_RETURN;
ips[times*2] = ip;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
ips[(times*2)+1] = ip;
UINT s = SendInput((times*2)+2, &ips[0], sizeof(INPUT));
err = GetLastError();
return s;
}
完成这项工作后,我还有更多工作要做,点击,将一些数字写入文本框等,之后我必须将combox选项恢复为默认值:
//combobox show
PutSingleClick(clickSettings.GetHandler, clickSettings.GetInstruments.GetX, clickSettings.GetInstruments.GetY);
Thread.Sleep(1000);
//uparrows
b = PutKeystroke(hWndMain, (int)lev.symbol + 15, FALSE, out eb);
Thread.Sleep(1000);
如果一切正常(没有异常发生,请解锁最顶层的浏览器并查看结果:
finally
{
SetWindowPos(GetParent(clickSettings.GetHandler), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
ShowWindow(GetParent(clickSettings.GetHandler), SW_HIDE);
MessageBox.Show(string.Format("Keystrokes: choosing {0} error {1}, return to all {2} error {3}", a, ea, b, eb));
if (isException)
{
MessageBox.Show(String.Format("Exception: {0} ", mess));
}
else
{
if (pix == PIXEL_COLOR.PIX_GREEN)
{ .........
我有总体上肯定结果(击键:选择X,错误0,返回Y,错误0),但是组合是画图,但没有笔画完成。< / p>
怎么了?
非常感谢
以下最简单,完整且可验证的示例 主要是为www.highlow.net上的HighLow经纪人自动使用Web应用程序而设计的程序。你需要点击“打开一个演示”(它是免费的,无需注册),右边会有一些组合框,这是问题的对象。
**** C#控制台应用代码****
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Globalization;
namespace clickTest1
{
class Program
{
enum SYMBOLS
{
AUDJPY, AUDNZD, CADJPY, CHFJPY, EURAUD, EURGBP,
EURJPY, EURUSD, GBPAUD, GBPJPY, GBPUSD, NZDJPY,
NZDUSD, USDCAD, USDCHF, USDJPY, GOLD, UNKNOWN
};
const int SW_SHOWMAXIMIZED = 3;
const int SW_HIDE = 0;
const uint SWP_NOSIZE = 0x0001;
const uint SWP_NOMOVE = 0x0002;
const uint SWP_SHOWWINDOW = 0x0040;
[DllImport(@"tradeInterop.dll")]
public static extern void PutSingleClick(IntPtr hwnd, int x, int y);
[DllImport(@"tradeInterop.dll")]
public static extern uint PutKeystroke(IntPtr shouldBeNULL, int times, int isDown, out int err);
[DllImport(@"user32.dll")]
public static extern int SetWindowPos(IntPtr hwnd, IntPtr precendingHwnd, int x, int y, int cx, int cy, uint flags);
[DllImport(@"user32.dll")]
public static extern int ShowWindow(IntPtr hwnd, int cmdShow);
[DllImport(@"user32.dll")]
public static extern IntPtr GetParent(IntPtr hwnd);
static void Main(string[] args)
{
UInt32 handler = 0;
int x, y = 0;
int keystrokesCount = 0;
IntPtr HWND_BOTTOM = new IntPtr(1);
IntPtr HWND_TOPMOST = new IntPtr(-1);
UInt32 originalHandler = 0;
while (true)
{
Console.WriteLine("H WND (hexadecimal) 0 = exit: ");
handler = UInt32.Parse(Console.ReadLine(), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
if (handler == 0)
{
ShowBrowser((IntPtr)originalHandler, IntPtr.Zero);
break;
}
originalHandler = handler;
HideBrowser((IntPtr)handler, HWND_BOTTOM);
Console.WriteLine("X: ");
x = int.Parse(Console.ReadLine());
Console.WriteLine("Y: ");
y = int.Parse(Console.ReadLine());
Console.WriteLine("Choose instrument index (e.g. EURUSD=7)");
keystrokesCount = int.Parse(Console.ReadLine());
Console.WriteLine("Getting browser maximized and topomost");
ShowBrowser((IntPtr)handler, HWND_TOPMOST);
Console.WriteLine("Clicking on combobox");
PutSingleClick((IntPtr)handler, x, y);
Thread.Sleep(1000); // for content of combo full load
Console.WriteLine("Putting keystrokes");
int lastErr = -1;
uint strokesPut = PutKeystroke(IntPtr.Zero, keystrokesCount, 1, out lastErr); // 1 = TRUE, is key down
System.Threading.Thread.Sleep(5000);
HideBrowser((IntPtr)handler, HWND_BOTTOM);
Console.WriteLine("Keys down pressed, {0} would be choosen", (SYMBOLS)keystrokesCount);
Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
Console.WriteLine("Press enter to continue");
Console.ReadLine();
ShowBrowser((IntPtr)handler, HWND_TOPMOST);
PutSingleClick((IntPtr)handler, x, y);
Thread.Sleep(1000);
strokesPut = PutKeystroke(IntPtr.Zero, keystrokesCount + 5, 0, out lastErr);
System.Threading.Thread.Sleep(5000);
HideBrowser((IntPtr)handler, HWND_BOTTOM);
Console.WriteLine("Keys up pressed, ALL would be choosen");
Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
Console.WriteLine("Press enter to continue");
Console.ReadLine();
}
}
private static void ShowBrowser(IntPtr hwnd, IntPtr precHwnd)
{
Console.WriteLine("Showing browser...");
ShowWindow(GetParent(hwnd), SW_SHOWMAXIMIZED);
SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
private static void HideBrowser(IntPtr hwnd, IntPtr precHwnd)
{
Console.WriteLine("Hiding browser...");
SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
ShowWindow(GetParent(hwnd), SW_HIDE);
}
}
**** TradeInterop dll及其相关功能****
int _stdcall DllMain(HINSTANCE hInst, DWORD fdwReason, PVOID pvReserved)
{
return true;
}
extern "C" __declspec(dllexport) void __stdcall PutSingleClick(HWND hwnd, int x, int y, BOOL needFocus = TRUE)
{
if(needFocus == TRUE)
{
SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(0,0));
SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(0,0));
}
SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(x, y));
}
extern "C" __declspec(dllexport) UINT __stdcall PutKeystroke(HWND hnd, int index, BOOL isDown, int& err)
{
INPUT ip = {0};
ip.type = INPUT_KEYBOARD;
ip.ki.wVk =isDown? VK_DOWN : VK_UP;
int times;
if(index < 2)
times = index+1;
else
times = index+2;
INPUT ips[100] = {0};
for(int i = 0; i < times*2; i+=2)
{
ip.ki.dwFlags = 0;
ips[i] = ip;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
ips[i+1] = ip;
}
ip.ki.dwFlags = 0;
ip.ki.wVk = VK_RETURN;
ips[times*2] = ip;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
ips[(times*2)+1] = ip;
err = -1;
UINT s = SendInput((times*2)+2, &ips[0], sizeof(INPUT));
err = GetLastError();
return s;
}
重申C#部分与戴维斯的想法和建议,遗憾的是问题仍然存在
using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Windows.Forms;
namespace clickTest1
{
class Program
{
enum SYMBOLS
{
AUDJPY, AUDNZD, CADJPY, CHFJPY, EURAUD, EURGBP,
EURJPY, EURUSD, GBPAUD, GBPJPY, GBPUSD, NZDJPY,
NZDUSD, USDCAD, USDCHF, USDJPY, GOLD, UNKNOWN
};
const int SW_SHOWMAXIMIZED = 3;
const int SW_HIDE = 0;
const uint SWP_NOSIZE = 0x0001;
const uint SWP_NOMOVE = 0x0002;
const uint SWP_SHOWWINDOW = 0x0040;
[DllImport(@"tradeInterop.dll")]
public static extern void PutSingleClick(IntPtr hwnd, int x, int y);
/*[DllImport(@"tradeInterop.dll")]
public static extern uint PutKeystroke(IntPtr shouldBeNULL, int times, int isDown, out int err);*/
[DllImport(@"user32.dll")]
public static extern int SetWindowPos(IntPtr hwnd, IntPtr precendingHwnd, int x, int y, int cx, int cy, uint flags);
[DllImport(@"user32.dll")]
public static extern int ShowWindow(IntPtr hwnd, int cmdShow);
[DllImport(@"user32.dll")]
public static extern IntPtr GetParent(IntPtr hwnd);
static void Main(string[] args)
{
UInt32 handler = 0;
int x, y = 0;
int keystrokesCount = 0;
IntPtr HWND_BOTTOM = new IntPtr(1);
IntPtr HWND_TOPMOST = new IntPtr(-1);
UInt32 originalHandler = 0;
while (true)
{
Console.WriteLine("H WND (hexadecimal) 0 = exit: ");
handler = UInt32.Parse(Console.ReadLine(), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
if (handler == 0)
{
ShowBrowser((IntPtr)originalHandler, IntPtr.Zero);
break;
}
originalHandler = handler;
HideBrowser((IntPtr)handler, HWND_BOTTOM);
Console.WriteLine("X: ");
x = int.Parse(Console.ReadLine());
Console.WriteLine("Y: ");
y = int.Parse(Console.ReadLine());
Console.WriteLine("Choose instrument index (e.g. EURUSD=7)");
keystrokesCount = int.Parse(Console.ReadLine());
Console.WriteLine("Getting browser maximized and topomost");
ShowBrowser((IntPtr)handler, HWND_TOPMOST);
Console.WriteLine("Clicking on combobox");
PutSingleClick((IntPtr)handler, x, y);
Thread.Sleep(1000); // for content of combo full load
Console.WriteLine("Putting keystrokes");
for (int i = 0; i < (keystrokesCount < 2 ? keystrokesCount+1 : keystrokesCount+2); i++)
{
SendKeys.SendWait("{DOWN}");
}
SendKeys.SendWait("{ENTER}");
System.Threading.Thread.Sleep(5000);
HideBrowser((IntPtr)handler, HWND_BOTTOM);
Console.WriteLine("Keys down pressed, {0} would be choosen", (SYMBOLS)keystrokesCount);
//Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
Console.WriteLine("Press enter to continue");
Console.ReadLine();
ShowBrowser((IntPtr)handler, HWND_TOPMOST);
PutSingleClick((IntPtr)handler, x, y);
Thread.Sleep(1000);
for (int i = 0; i < keystrokesCount+5; i++)
{
SendKeys.SendWait("{UP}");
}
SendKeys.SendWait("{ENTER}");
System.Threading.Thread.Sleep(5000);
HideBrowser((IntPtr)handler, HWND_BOTTOM);
Console.WriteLine("Keys up pressed, ALL would be choosen");
//Console.WriteLine("From library: Sent {0} strokes, error: {1}", strokesPut, lastErr);
Console.WriteLine("Press enter to continue");
Console.ReadLine();
}
}
private static void ShowBrowser(IntPtr hwnd, IntPtr precHwnd)
{
Console.WriteLine("Showing browser...");
ShowWindow(GetParent(hwnd), SW_SHOWMAXIMIZED);
SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
private static void HideBrowser(IntPtr hwnd, IntPtr precHwnd)
{
Console.WriteLine("Hiding browser...");
SetWindowPos(GetParent(hwnd), precHwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
ShowWindow(GetParent(hwnd), SW_HIDE);
}
}
}