// IEのウィンドウハンドルの取得 var ieHandle = NativeMethods.FindWindowEx(IntPtr.Zero, IntPtr.Zero, "IEFrame", IntPtr.Zero); |
static class FlashHandle { static readonly string FlashHandleString = "MacromediaFlashPlayerActiveX"; static List<IntPtr> handles = new List<IntPtr>(); public static IntPtr Get() { // IEのウィンドウハンドルの取得 var ieHandle = NativeMethods.FindWindowEx(IntPtr.Zero, IntPtr.Zero, "IEFrame", IntPtr.Zero); // IEの子ウィンドウのハンドルを列挙 NativeMethods.EnumChildWindows(ieHandle, EnumWindowProc, IntPtr.Zero); // FlashPlayerのウィンドウハンドルの取得 foreach(var handle in handles) { var sb = new StringBuilder(256); NativeMethods.GetClassName(handle, sb, sb.Capacity); if (sb.ToString() == FlashHandleString) return handle; } return IntPtr.Zero; } static bool EnumWindowProc(IntPtr handle, IntPtr lParam) { handles.Add(handle); return true; } } |
// FlashPlayerハンドルの取得 var flashHandle = FlashHandle.Get(); |
class MessageSender { const int MK_LBUTTON = 0x0001; const int WM_LBUTTONDOWN = 0x0201; const int WM_LBUTTONUP = 0x0202; IntPtr windowHandle; public MessageSender(IntPtr windowHandle) { this.windowHandle = windowHandle; } public void Click(uint xPos, uint yPos) { var lParam = (xPos & 0xFFFF) | (yPos << 16); NativeMethods.SendMessage(windowHandle, WM_LBUTTONDOWN, MK_LBUTTON, lParam); NativeMethods.SendMessage(windowHandle, WM_LBUTTONUP, 0x00000000, lParam); } } |
var messageSender = new MessageSender(flashHandle); while (true) { messageSender.Click(700, 400); await Task.Delay(50); } |
const int WM_KEYDOWN = 0x0100; public void Key(KeyCode key) { var wParam = (uint)key; NativeMethods.SendMessage(windowHandle, WM_KEYDOWN, wParam, (uint)IntPtr.Zero); } |
enum KeyCode : uint { VK_KEY_1 = 0x31, VK_KEY_2, VK_KEY_3, VK_KEY_4, VK_KEY_5, VK_KEY_6, VK_KEY_7, VK_KEY_8, VK_KEY_9,} |
public static IplImage GrayCapture(IntPtr handle) { var rect = new Native.NativeMethods.RECT(); Native.NativeMethods.GetClientRect(handle, out rect); using (var img = new Bitmap(rect.right, rect.bottom, PixelFormat.Format32bppRgb)) { using (var memg = Graphics.FromImage(img)) { var dc = memg.GetHdc(); Native.NativeMethods.PrintWindow(handle, dc, 0); memg.ReleaseHdc(dc); } using (var screenImage = BitmapConverter.ToIplImage(img)) { var screenGrayImage = Cv.CreateImage(new CvSize(img.Width, img.Height), BitDepth.U8, 1); Cv.CvtColor(screenImage, screenGrayImage, ColorConversion.BgrToGray); return screenGrayImage; } } } |
(img.depth() == CV_8U || img.depth() == CV_32F) && img.type() == templ.type() |
protected bool Match(IplImage screenImage, IplImage tmplImage) { using (var result = new CvMat(screenImage.Height - tmplImage.Height + 1, screenImage.Width - tmplImage.Width + 1, MatrixType.F32C1)) { Cv.MatchTemplate(screenImage, tmplImage, result, MatchTemplateMethod.CCoeffNormed); double minVal; double maxVal; var minPoint = new CvPoint(); var maxPoint = new CvPoint(); // Val = 相関係数, max/min = 最大/最小の相関係数または相関係数の座標を格納する Cv.MinMaxLoc(result, out minVal, out maxVal, out minPoint, out maxPoint); // 0.73, 0.82, 0.93あたりの値は確認済み, 暫定的に閾値を0.7にしておく if (maxVal > 0.7) { X = (uint)maxPoint.X; Y = (uint)maxPoint.Y; return true; } else { X = default(uint); Y = default(uint); return false; } } } |
while (true) { using (var screen = ScreenCapture.GrayCapture(flashHandle)) { var recognizers = new ImageRecognitionBase[] { new Clickable(), }; foreach(var recognizer in recognizers) { if (recognizer.Check(screen)) sender.Click(recognizer.X, recognizer.Y); } } Thread.Sleep(15000); } |
const int WM_HOTKEY = 0x0312; const int HOTKEY_ID = 0x0001; |
public MainForm() { // ホットキーの登録 Native.NativeMethods.RegisterHotKey(this.Handle, HOTKEY_ID, 0, (int)Keys.F2); } |
protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == WM_HOTKEY) { if ((int)m.WParam == HOTKEY_ID) { // ホットキーが入力された時の処理 if (client == null) startButton.PerformClick(); else stopButton.PerformClick(); } } } |
private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // ホットキーの解除 Native.NativeMethods.UnregisterHotKey(this.Handle, HOTKEY_ID); } |