сообщение от mouse_event - PullRequest
       1

сообщение от mouse_event

0 голосов
/ 24 января 2012
#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);
}

Я ожидал получить круг, но получить декагон) Я звонил mouse_event 10000 раз в этой программе. Сообщение WM_MOUSEMOVE было обработано 10 раз (то же самое с таймером). то есть вызовы mouse_event (1000 раз) не были отправлены в очередь сообщений, кроме одного из 1000. В чем причина?

Ответы [ 3 ]

3 голосов
/ 24 января 2012

Сообщение WM_MOUSEMOVE является коалесцирующим сообщением.Если происходит событие mouse_event и приложение еще не обработало предыдущее событие mouse_event , то предыдущее исключается.В вашем случае вы сгенерировали 1000 mouse_events без промежуточной рассылки сообщений, поэтому все, кроме последнего, выбрасываются.

1 голос
/ 24 января 2012
        for (int i=0;i<1000;i++)
        {
            // etc...
        }

Как я объяснил в вашем предыдущем вопросе, Windows может вызывать обратный вызов перехвата, только когда ваш поток прокачивает цикл сообщений. не выполняет какую-либо накачку, пока ваш код выполняется внутри цикла for (). В результате Windows накапливает все генерируемые вами события мыши в одном сообщении о перемещении мыши. Вы получите его при выходе из цикла for ().

0 голосов
/ 24 января 2012

Возможно, вы вызываете mouse_event через слишком короткий промежуток времени.Это зависит от пороговых значений мыши в настройках Win.Вы можете зондировать манипулирование SystemParametersInfo (...) с помощью uiAction = SPI_GETMOUSE.

В конце концов вы можете синхронизировать WM_MOUSEMOVE и mouse_event - отправлять mouse_event после успеха с WM_MOUSEMOVE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...