当鼠标按钮按下时,WM_LBUTTONDOWN不会立即发送

WM_LBUTTONDOWN not sent immediately when mouse button is down

本文关键字:LBUTTONDOWN WM 按钮 鼠标      更新时间:2023-10-16

在Windows 10中,当用C++按下鼠标左键时,我无法准确检测。

我尝试了两种方法:

  1. 捕获WM_LBUTTONDOWN消息

  2. 直接使用GetKeyState(VK_LBUTTON)

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

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

  2. 返回的GetKeyState(VK_LBUTTON)值恰好在发送WM_LBUTTONDOWN时发生变化,也就是说,在我按下鼠标按钮 0.5秒后

发送WM_LBUTTONDOWN

  1. 如果我只用左键点击
  2. 如果在移动鼠标时按下鼠标

但我仍然不知道在长时间按下左键而不移动鼠标的情况下,如何在按下左键时立即检测。有什么事我不知道吗?Windows是否迫使我们按照自己的方式思考并使用它的"点击"answers"鼠标"?我的意思是,窗口没有办法准确检测何时按下鼠标按钮吗?如何在窗口中用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;
}

您的程序在我的电脑上运行良好:当我按下按钮时,我没有注意到任何延迟。windows消息似乎在您的计算机上被截获的级别很低。你会使用鼠标识别引擎,比如"Sensiva"、"Just Gesture"或"Stroke it"吗?这可以解释你的问题。