次のいずれかを実行しようとしています 1.目的のプログラムを開き、プログラムでキーを押します 2.プログラムの開いているウィンドウを見つけて、プログラムでキーを押します(どちらでも構いません)
SendKeys.SendWait()、PostMessage()、および SendMessage() の多数の実装を試みましたが、失敗しました。以下は私のコードスニペットです
//included all these for attempts
[DllImport("User32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
[DllImport("user32.dll")]
static extern byte VkKeyScan(char ch);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
ウィンドウのハンドル、sendmessage/postmessage/sendkeys で使用される変数を取得する
IntPtr ptrOBS = proc.Handle;//this works properly, proc is instantiated properly
//IntPtr ptrOBS = FindWindow(null, "Open Broadcaster Software v0.472b");
SetForegroundWindow(ptrOBS);
const UInt32 WM_CHAR = 0x0102;
const uint WM_KEYDOWN = 0x100;
const int VK_R = 0x52; // taken from http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx
const int VK_S = 0x53;
SendMessage 試行:
SendMessage(ptrOBS, WM_KEYDOWN, (IntPtr)VK_R, (IntPtr)1);//tried both WM_CHAR and WM_KEYDOWN
PostMessage 試行:
string message = "rs";
bool sent = PostMessage(ptrOBS, WM_KEYDOWN, VkKeyScan(message[0]), 0);
SendKeys 試行:
SendKeys.SendWait("{r}");
親ウィンドウ(アプリケーション)と子ウィンドウ(送信しようとしているキープレスによってトリガーされるボタン)で SetFocus を試しました:
static void SetFocus(IntPtr hwndTarget, string childClassName)
{
// hwndTarget is the other app's main window
// ...
IntPtr targetThreadID = GetWindowThreadProcessId(hwndTarget, IntPtr.Zero); //target thread id
IntPtr myThreadID = GetCurrentThread(); // calling thread id, our thread id
try
{
bool lRet = AttachThreadInput(myThreadID, targetThreadID, -1); // attach current thread id to target window
// if it's not already in the foreground...
lRet = BringWindowToTop(hwndTarget);
SetForegroundWindow(hwndTarget);
// if you know the child win class name do something like this (enumerate windows using Win API again)...
IntPtr hwndChild = (IntPtr)1183492;//(IntPtr)EnumAllWindows(hwndTarget, childClassName).FirstOrDefault();
if (hwndChild == IntPtr.Zero)
{
// or use keyboard etc. to focus, i.e. send keys/input...
// SendInput (...);
return;
}
// you can use also the edit control's hwnd or some child window (of target) here
SetFocus(hwndChild); // hwndTarget);
SendKeys.SendWait("{r}");
}
finally
{
SendKeys.SendWait("{r}");
bool lRet = AttachThreadInput(myThreadID, targetThreadID, 0); //detach from foreground window
SendKeys.SendWait("{r}");
}
}
NSGaga の場合:
string windowName = "Open Broadcaster Software v0.472b";
IntPtr outerPtr = FindWindow(null, windowName);
IntPtr ptrOBS = (IntPtr)527814;//button that im trying to trigger keypress on
SetForegroundWindow(outerPtr);
SetForegroundWindow(ptrOBS);
SetFocus(outerPtr, "OBSWindowClass");//SetFocus(ptrOBS, "Button");
const UInt32 WM_CHAR = 0x0102;
const int VK_R = 0x52; // taken from http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx
const int VK_S = 0x53;
//SetForegroundWindow(ptrOBS);
System.Threading.Thread.Sleep(3000);
SendKeys.SendWait("{r}");
SendMessage(outerPtr, WM_KEYDOWN, (IntPtr)VK_R, (IntPtr)1);
PostMessage(outerPtr, WM_KEYDOWN, VkKeyScan('r'), 0);