'There is no "MouseButtons" information in "MOUSEMOVE" of 'winapi'
I'm trying to implement LBUTTONDOWN->MOUSEMOVE->WM_LBUTTONUP using winapi in outfocus. But the "MouseButtons" information doesn't come.
I want to simulate the same mouse click and move using winapi.
I created a winform application to make sure winapi works. This form Event monitors mouse and keyboard input.
Using
SendMessage LBUTTONDOWN-> MOUSEMOVE-> WM_LBUTTONUP
message has been sent.
But my code doesn't give the button information during MOUSEMOVE.
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, IntPtr lParam);
Here is my code.
int x = 0;
int y = 0;
IntPtr lparam = IntPtr.Zero;
x = 160;
y = 500;
lparam = new IntPtr(x | (y << 16));
SendMessage(hwnd_child, WM_LBUTTONDOWN, (int)0x0, lparam);
Thread.Sleep(3000);
//이벤트
for (int i = 0; i < 100; ++i)
{
//일반
x = 160;
y = 500 - i;
lparam = new IntPtr(x | (y << 16));
SendMessage(hwnd_child, WM_MOUSEMOVE, 0, lparam);
//Thread.Sleep(10);
}
x = 160;
y = 500 - 100;
lparam = new IntPtr(x | (y << 16));
SendMessage(hwnd_child, WM_LBUTTONUP, (int)0x0, lparam);
Existing result (See Previous image)
2019-09-02 Added
I modified the code in the way of the answer.
I checked the log through spy++.
Modified code
//SendMessage -> PostMessage
PostMessage(hwnd_child, WM_MOUSEMOVE, MK_LBUTTON, lparam);
Desired result.
Log obtained by dragging the mouse directly.
test program code
private void FrmMain_MouseMove(object sender, MouseEventArgs e)
{
if (this.m_bMouseMoveEnabled == true)
{
this.SendLog("MouseMove"
, string.Format("Btn:{0}, X:{1}, Y:{2}"
, e.Button
, e.X
, e.Y));
}
}
2022-05-04 Update
I have created several test programs.
And I found the cause.
The 'MOUSEMOVE' information of 'winapi' appears to be that of a physical mouse.
I have "MouseButtons" when I hold down the physics mouse.
Solution 1:[1]
As @Flydog57 said, you can change the wParam
parameter of SendMessage
to MK_LBUTTON
.
This allows you to press the left button while the mouse is moving. I tested it and found it works.
Like this:
SendMessage(hwnd_child, WM_MOUSEMOVE, MK_LBUTTON, lparam);
You can refer WM_MOUSEMOVE for more details.
Or you can use SendInput, which I recommend more.
This is the smallest code example shown with SendInput.
The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput.
Although it's written in C++, it gives you a good idea.
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
#define X 160
#define Y 500
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 800
void MouseClickDOWN(INPUT *buffer)
{
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN);
SendInput(1, buffer, sizeof(INPUT));
}
int main(int argc, char *argv[])
{
int i = 0;
INPUT input;
INPUT buffer[101];
memset(&input,0,sizeof(INPUT));
memset(buffer,0, sizeof(INPUT)*101);
input.mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN);
SendInput(1, &input, sizeof(INPUT));
Sleep(3000);
for (i; i < 100; ++i)
{
buffer[i].mi.dx = (X* (0xFFFF / SCREEN_WIDTH));
buffer[i].mi.dy = ((Y - i) * (0xFFFF / SCREEN_HEIGHT));
buffer[i].mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
}
buffer[i].mi.dwFlags = (MOUSEEVENTF_LEFTUP);
SendInput(101, buffer, sizeof(INPUT));
return 0;
}
You can view the details of the simulate mouse from the MOUSEINPUT structure.
I've found some other considerations for using SendInput
in C#, please refer this.
Why do I recommend SendInput instead of SendMessage?
I think the charm of SendInput lies in its ability to synthesize keystrokes and reduce overhead.
Thank you in particular for @Remy Lebeau's help.
Updated:
Call SendMessage
Call PostMessage
I tested SendMessage
and PostMessage
separately, both of which could be tested by pressing the left mouse button while moving.
The difference between SendMessage and PostMessage is:
PostMessage
(in "pure windows programming", aka win32 API) is asynchronous, i.e., to quote the docs:
Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.
To post a message in the message queue associated with a thread, use the PostThreadMessage function.
SendMessage
is synchronous, that is, again quoting:
Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.
To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a message to a thread's message queue and return immediately, use the PostMessage or PostThreadMessage function.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |