当鼠标按钮按下时,WM_LBUTTONDOWN不会立即发送
WM_LBUTTONDOWN not sent immediately when mouse button is down
在Windows 10中,当用C++按下鼠标左键时,我无法准确检测。
我尝试了两种方法:
-
捕获
WM_LBUTTONDOWN
消息 -
直接使用
GetKeyState(VK_LBUTTON)
每次,行为都是一样的:
如果我在一秒钟内按下左键,
-
WM_LBUTTONDOWN
在我按下后约0.5秒发送左键 -
返回的
GetKeyState(VK_LBUTTON)
值恰好在发送WM_LBUTTONDOWN时发生变化,也就是说,在我按下鼠标按钮 0.5秒后
发送WM_LBUTTONDOWN
:
- 如果我只用左键点击
- 如果在移动鼠标时按下鼠标
但我仍然不知道在长时间按下左键而不移动鼠标的情况下,如何在按下左键时立即检测。有什么事我不知道吗?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"吗?这可以解释你的问题。