简体   繁体   English

来自mouse_event的消息

[英]message from mouse_event

#include <windows.h>
#include <time.h>
#define _USE_MATH_DEFINES 
#include <math.h>

LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
    static wchar_t szAppName[]=L"circle";
    HWND hwnd;
    MSG msg;
    WNDCLASSEX wndclass;

    wndclass.cbSize=sizeof(wndclass);
    wndclass.style=CS_HREDRAW|CS_VREDRAW;
    wndclass.lpfnWndProc=WndProc;
    wndclass.cbClsExtra=0;
    wndclass.cbWndExtra=0;
    wndclass.hInstance=hInstance;
    wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName=NULL;
    wndclass.lpszClassName=szAppName;
    wndclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);

    RegisterClassEx(&wndclass);

    hwnd=CreateWindow(szAppName,L"circle",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_MAXIMIZE);
    UpdateWindow(hwnd);
    SetTimer(hwnd,0,1,0);
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
const int CENTER=300;
const int RADIUS=100;
LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static HDC wndDC=GetDC(hwnd);
    switch(iMsg)
    {
    case WM_CREATE:
        {
            MoveToEx(wndDC,CENTER+RADIUS,CENTER,0);
            mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE, (CENTER+RADIUS)*(65535.0/1366),(CENTER)*(65535.0/768),0,0);
            return 0;
        }
    case WM_PAINT:
        {
            hdc=BeginPaint(hwnd,&ps);
            EndPaint(hwnd,&ps);
            return 0;
        }
    case WM_MOUSEMOVE:
        LineTo(wndDC,LOWORD(lParam),HIWORD(lParam));
        return 0;
    case WM_TIMER:
        {
            srand(clock());
            static int count=0;
            for (int i=0;i<1000;i++)
            {
                count++;
                mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE, (CENTER+RADIUS*cos(2*M_PI*count/10000))*(65535.0/1366),
                    (CENTER+100*sin(2*M_PI*count/10000))*(65535.0/768),0,0);
            }
            if (count==10000)
                KillTimer(hwnd,0);
            return 0;
        }
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd,iMsg,wParam,lParam);
}

I expected to get circle but get decagon) I called mouse_event 10000 times in this program. 我希望得到圆,但得到十边形)我在此程序中调用了mouse_event 10000次。 Message WM_MOUSEMOVE was handled 10 times (same with timer). 消息WM_MOUSEMOVE已处理10次(与计时器相同)。 ie mouse_event calls (1000 times) weren't sended in message queue except for one from 1000. What is reason for it? 即mouse_event调用(1000次)没有发送到消息队列中,只有1000个除外。这是什么原因?

The WM_MOUSEMOVE message is a coalescing message. WM_MOUSEMOVE消息是合并消息。 If a mouse_event happens and the application has not yet processed the previous mouse_event , then the previous one is thrown away. 如果发生mouse_event, 而应用程序尚未处理上一个mouse_event ,那么将丢弃前一个mouse_event In your case, you generated 1000 mouse_events with no intervening message pump, so all but the last one gets thrown away. 在您的情况下,您生成了1000个mouse_events,而没有中间消息泵,因此除了最后一个消息泵外,所有其他事件都被丢弃。

        for (int i=0;i<1000;i++)
        {
            // etc...
        }

As I explained in your previous question, Windows can only call the hook callback when your thread is pumping the message loop. 正如我在上一个问题中所解释的那样,Windows仅在您的线程正在泵送消息循环时才能调用钩子回调。 It is not doing any pumping while your code is executing inside this for() loop. 当您的代码在此for()循环内执行时,它没有进行任何泵送。 As a result, Windows accumulates all the mouse events you generate into a single mouse move message. 结果,Windows将您生成的所有鼠标事件累积到单个鼠标移动消息中。 You'll get it when the for() loop exits. 当for()循环退出时,您将获得它。

Probably you call mouse_event after too short time interval. 可能是在时间间隔过短之后调用mouse_event。 It depend from mouse threshold values in Win settings. 它取决于Win设置中的鼠标阈值。 You may probe manipulate SystemParametersInfo(...) with uiAction = SPI_GETMOUSE. 您可以使用uiAction = SPI_GETMOUSE探测操纵SystemParametersInfo(...)。

Eventually you may sychronize WM_MOUSEMOVE and mouse_event - send mouse_event after success with WM_MOUSEMOVE. 最终,您可能会同步WM_MOUSEMOVE和mouse_event-使用WM_MOUSEMOVE成功后发送mouse_event。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM