鼠标按钮关闭时不立即发送WM_LBUTTONDOWN

时间:2017-11-18 10:07:54

标签: c++ winapi mouseevent windows-messages

我无法准确地检测到在Windows 10中用C ++按下鼠标左键的时间。

我试过两种方法:

  1. 抓住WM_LBUTTONDOWN消息

  2. 直接使用GetKeyState(VK_LBUTTON)

  3. 每次行为都是一样的:
    如果我在一秒钟内按下左按钮,

    1. 我按下后约0.5秒发送WM_LBUTTONDOWN 左键

    2. 当发送WM_LBUTTONDOWN时,返回的GetKeyState(VK_LBUTTON)值会发生更改,这意味着我按下鼠标按钮后0.5秒

    3. WM_LBUTTONDOWN已发送:

      1. 如果我只点击并使用左键
      2. 如果我在移动鼠标的同时按下鼠标
      3. 但是,如果长按左按钮而不移动鼠标,我仍然不知道如何立即检测。 有没有我不了解的事件? Windows是否会强迫我们思考它的方式并使用它的" CLICK"和它的" MOUSEDOWN" ?我的意思是,有没有办法用Windows来确切地检测何时按下鼠标按钮? 如何准确检测Windows中用C ++按下左键的时间?

        编辑:

        感谢您的回答。 我制作了一个最小的完整且可验证的代码来向您展示。

        下面的程序使用Visual C ++ 2017进行编译 它显示了一个蓝色矩形,每次GetMessage获取一条消息时都会移动。 矩形变为红色,并在检测到WM_LBUTTONDOWN时向下平移。

        正如我在第一篇文章中所描述的那样:当您单击或在移动鼠标时按下鼠标按钮时,您将看到矩形变为红色,但如果按下左侧则需要大约0.5秒变为红色按钮,不要移动鼠标。

        再次感谢您的帮助。

        以下是代码:

        #include <Windows.h>
        #include <GL/GL.h>
        #include <math.h>
        #pragma comment(lib, "opengl32.lib")
        
        HDC   hdc;
        HGLRC hrc;
        bool ButtonL;
        
        void MyDisplay()
        {
            static float kk=0; kk+=0.04f;
            glMatrixMode(GL_MODELVIEW); glLoadIdentity();glTranslated(0.5*sin(kk),0,0);
            glMatrixMode(GL_PROJECTION); glLoadIdentity();
            glClearColor(0, 0, 0, 0);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            if ((GetKeyState(VK_LBUTTON) & 0x100) != 0) glColor3f(1,0,0); else glColor3f(0,0,1);
            if (ButtonL) glTranslated(0,-0.5,0);
            glBegin(GL_QUADS);  glVertex2f(0,0);    glVertex2f(0,1);    glVertex2f(1,1);    glVertex2f(1,0);    glEnd();
        }
        LRESULT CALLBACK WndProc(HWND   hWnd, UINT   uMsg, WPARAM   wParam, LPARAM  lParam)
        {
                switch (uMsg)
                {
                    case WM_LBUTTONDOWN  : ButtonL=true;  break;
                    case WM_LBUTTONUP    : ButtonL=false; break;
                }
                return DefWindowProc(hWnd,uMsg,wParam,lParam);
        }
        
        int main(int argc, char** argv)
        {
            ButtonL=false;
            WNDCLASS    wc;         
            RECT        WindowRect; 
            WindowRect.left   =(long)0; WindowRect.right  =(long)400;
            WindowRect.top    =(long)0; WindowRect.bottom =(long)300;
            HINSTANCE hInstance     = GetModuleHandle(NULL);           
            wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
            wc.lpfnWndProc      = (WNDPROC) WndProc;                    
            wc.cbClsExtra       = 0;                            
            wc.cbWndExtra       = 0;                        
            wc.hInstance        = hInstance;                    
            wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);  
            wc.hCursor          = LoadCursor(NULL, IDC_ARROW);  
            wc.hbrBackground    = NULL;                         
            wc.lpszMenuName     = NULL;                         
            wc.lpszClassName    = "OpenGL";                     
        
            if (!RegisterClass(&wc)) return(0);
        
            AdjustWindowRectEx(&WindowRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);    
            HWND hWnd=CreateWindowEx(   WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,"OpenGL","Titre",WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 
                                        WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top,NULL,NULL,hInstance,NULL);
            PIXELFORMATDESCRIPTOR pfd=
            {   sizeof(PIXELFORMATDESCRIPTOR),1,PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,PFD_TYPE_RGBA,32, 0, 0, 0, 0, 0, 0,              
                0,0,0,0, 0, 0, 0,16,0,0,PFD_MAIN_PLANE,0,0, 0, 0                            
            };
        
            hdc=GetDC(hWnd);
            GLuint PixelFormat=ChoosePixelFormat(hdc,&pfd);
            SetPixelFormat(hdc,PixelFormat,&pfd);
            hrc = wglCreateContext(hdc);
            wglMakeCurrent(hdc , hrc);
            ShowWindow(hWnd,SW_SHOW);               // Show The Window
            SetForegroundWindow(hWnd);              // Slightly Higher Priority
            SetFocus(hWnd);                     // Sets Keyboard Focus To The Window
        
            MSG Msg;
            while( GetMessage( &Msg, hWnd, 0, 0 ) != 0)
            { 
                TranslateMessage(&Msg); 
                DispatchMessage(&Msg); 
                MyDisplay();
                SwapBuffers(hdc);
            }
            return 0;
        }
        

1 个答案:

答案 0 :(得分:2)

您的程序在我的计算机上正常工作:当我按下按钮时,我没有注意到任何延迟。 似乎Windows消息在您的计算机上以非常低的级别被截获。 您是否使用像“Sensiva”或“Just Gesture”或“Stroke it”这样的鼠标识别引擎? 它可以解释你的问题。