[英]How to simulate mouse click in a Directx game
I have a game written in Directx (not mine it's mmo game). 我有一个用Directx编写的游戏(不是我的mmo游戏)。 The game window isn't active (not minimized, just it's behind other windows but if is possible it can be minimized also).
游戏窗口未激活(未最小化,只是在其他窗口后面,但如果可能,也可以最小化)。
I want to simulate mouse click on x, y position. 我想模拟鼠标单击x,y位置。 Spy++ doesn't show anything in message when i'm clicking in game.
当我在游戏中单击时,Spy ++不会在消息中显示任何内容。
For now i did just that: 现在,我只是这样做:
private void start_Click(object sender, EventArgs e)
{
IntPtr ActualWindow = GetActiveWindow();
ShowWindow(hWnd, ShowWindowCommands.Restore); //show game window
Thread.Sleep(50); //a little slow down
ClickOnPoint(hWnd, new Point(692, 87)); //click on x,y
Thread.Sleep(50); //again a little slow down
ShowWindow(hWnd, ShowWindowCommands.Minimize);//minimize game window
ShowWindow(ActualWindow, ShowWindowCommands.Restore);//restore last active window
//sleep is needed for click, if i will do it too fast game will not detect the click
}
private void ClickOnPoint(IntPtr wndHandle, Point clientPoint)
{
POINT oldPoint;
GetCursorPos(out oldPoint);
ClientToScreen(wndHandle, ref clientPoint);
/// set cursor on coords, and press mouse
SetCursorPos(clientPoint.X, clientPoint.Y);
mouse_event(0x00000002, 0, 0, 0, UIntPtr.Zero); /// left mouse button down
Thread.Sleep(18);
mouse_event(0x00000004, 0, 0, 0, UIntPtr.Zero); /// left mouse button up
Thread.Sleep(15);
/// return mouse
SetCursorPos(oldPoint.X, oldPoint.Y);
}
It's restore game window click on point and minimize game window. 这是还原游戏窗口上的点击并最小化游戏窗口。
It's works good, but just when i'm not moving mouse... 它的工作原理很好,但是当我不移动鼠标时...
I search something else. 我搜索其他东西。 I want to click mouse without moving it for real.
我想单击鼠标而不真正移动它。 It's even possible do it in game?
在游戏中甚至有可能吗? I don't have any handle for button i want to click because it's a game...
我没有要单击的按钮的手柄,因为它是游戏...
PS Sorry for my english. PS对不起,我的英语。
Some of my code for simulating a mouse click on a non-active window looks like: 我的一些用于在非活动窗口上模拟鼠标单击的代码如下所示:
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PostMessage(int hWnd, uint Msg, int wParam, int lParam);
// int MouseX
// int MouseY
// public static readonly uint WM_LBUTTONUP = 0x202;
// public static readonly uint WM_LBUTTONDOWN = 0x201;
int lparam = MouseX & 0xFFFF | (MouseY & 0xFFFF) << 16;
int wparam = 0;
PostMessage(windowHandle, WM_LBUTTONDOWN, wparam, lparam);
Thread.Sleep(10);
PostMessage(windowHandle, WM_LBUTTONUP, wparam, lparam);
You can try using Sendiput. 您可以尝试使用Sendiput。 here is the Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx
这是文档: https : //msdn.microsoft.com/zh-cn/library/windows/desktop/ms646310(v=vs.85).aspx
Here is my example: 这是我的示例:
Includes: 包括:
#include <stdio.h>
#include <cstdlib>
#include <windows.h>
#include <winuser.h>
#include <conio.h>
INPUT input;
int x = 889;
int y = 451;
`// Mouse click up
input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.dx = x * float(65536 / GetSystemMetrics(SM_CXSCREEN)); //x being coord in pixels
input.mi.dy = y * float(65536 / GetSystemMetrics(SM_CYSCREEN)); //y being coord in pixels
input.mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN);
input.mi.time = 0;
SendInput(1, &input, sizeof(input));`
`
//Mouse click down
input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.dx = x * float(65536 / GetSystemMetrics(SM_CXSCREEN)); //x being coord in pixels
input.mi.dy = y * float(65536 / GetSystemMetrics(SM_CYSCREEN)); //y being coord in pixels
input.mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP);
input.mi.time = 0;
SendInput(1, &input, sizeof(input));`
And You can do something like this to make sure you are in the focused window:
HWND hWnd = ::FindWindowEx(0, 0, "YourGame - Use Spy++", 0);
DWORD dwThreadID = GetWindowThreadProcessId(hWnd, NULL);
AttachThreadInput(dwThreadID, GetCurrentThreadId(), true);
SetForegroundWindow(hWnd);
SetActiveWindow(hWnd);
SetFocus(hWnd);
AttachThreadInput(GetWindowThreadProcessId(GetForegroundWindow(), NULL),GetCurrentThreadId(), TRUE);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.