MOUSEEVENTF_MOVE_NOCOALESCE flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <windows.h>

void send_mouse_wheel(int dx, int dy) 
{
	INPUT input = { 0 };
	input.type = INPUT_MOUSE;

	if (dy != 0) {
		input.mi.dwFlags = MOUSEEVENTF_WHEEL | MOUSEEVENTF_MOVE_NOCOALESCE;
		input.mi.mouseData = dy;

		SendInput(1, &input, sizeof(INPUT));
	}

	if (dx != 0) {
		input.mi.dwFlags = MOUSEEVENTF_HWHEEL | MOUSEEVENTF_MOVE_NOCOALESCE;
		input.mi.mouseData = dx;

		SendInput(1, &input, sizeof(INPUT));
	}
}


In this code, what does MOUSEEVENTF_MOVE_NOCOALESCE do?

MSDN says 'The WM_MOUSEMOVE messages will not be coalesced.' for its description. But I didn't understand it and when I compiled with and without that flag, there didn't seem any distinction.
Last edited on
I would think 'coalesce' means that mouse move events are skipped. Hence 'no coalesce' would mean that you get more mouse move events which might slowing down the event processing.
Also here https://stackoverflow.com/questions/67956583/what-is-mouseeventf-move-nocoalesce-flag-in-winapi

My understanding (which could be wrong), is that usually if there is already a mouse movement event in the message queue, then that message is updated in the queue and a new message is not inserted in the queue. If MOVE_NOCOALESCE is used, then every mouse movement message is inserted in the message queue - even if there is already one present. The advantage of using coalesce is to cut down processing unnecessary mouse messages.
Last edited on
Then passing `MOUSEEVENTF_MOVE_NOCOALESCE` through SendInput() means WM_MOUSEMOVE can be processed by procedure while SendInput() works?
Or WM_MOUSEMOVE can't be inserted in message queue by not specifying `MOUSEEVENTF_MOVE_NOCOALESCE`(invoking default behavior) when I call SendInput()?

If I can't understand your(coder777) answer and the SO answer, should I rather read petzold's book? It seems strange that MSDN doesn't explain perfect detail and leave some ambiguity and people don't ask much about what I asked although it doesn't seem to be a corner case. Anyway thanks for reading and answering my question.
Last edited on
I see your edited comment after writing my one.
> if there is already a mouse movement event in the message queue, then that message is updated in the queue and a new message is not inserted in the queue. If MOUSEEVENTF_MOVE_NOCOALESCE is used, then every mouse movement message is inserted in the message queue

This sentence makes sense seeplus' and the link's answer although I still don't know what this happening affects the program during running time. Thank you it gets clearer.
Last edited on
Do you know what 'coalesce' means?
https://www.merriam-webster.com/dictionary/coalesce

From that you could infer that coalescing means that mouse movements are joined together.
Say 10,0 ; 20,0 ; 30,0 ; 40,0 ; 50,0 would be coalesced into 10,0 then 50,0.

Maybe you're not interested in the detail of how the mouse got to where it is, and are only interested in the best latest position available.

By prefixing "NO", what you're saying is that you don't want that to happen, and you want the full unadulterated message stream of every last minute detail of movement.

@salem c

>From that you could infer that coalescing means that mouse movements are joined together.
Say 10,0 ; 20,0 ; 30,0 ; 40,0 ; 50,0 would be coalesced into 10,0 then 50,0.

Thanks for intuitive explanation. I think all answers are based on the same principle so I get more and more sense each time I read them.

But let's consider this. When SendInput() is used for mouse input and MOUSEEVENTF_MOVE_NOCOALESCE bit is on, WM_MOUSEMOVE is not coalesced in the message queue.

What is the relation between not coalescing WM_MOUSEMOVE and sending mouse input? For example, in the source code I posted there seems no distinction by specifying MOUSEEVENTF_MOVE_NOCOALESCE. That is, input.mi.dwFlags = MOUSEEVENTF_WHEEL | MOUSEEVENTF_MOVE_NOCOALESCE; and input.mi.dwFlags = MOUSEEVENTF_WHEEL; these are not different but just cause some performance overhead.

It seems SendInput() with the MOUSEEVENTF_MOVE_NOCOALESCE lets message queue not to accumulate WM_MOUSEMOVE in global, not local to while the function runs. I think this setting should be done separately by a function like SetStateQueue()(which I made) or manipulating a structure like struct {T mouseEventF_move_nocoalesce; /* ... */ } QueueState;(I also made it in order to express my thought)
Last edited on
Topic archived. No new replies allowed.