作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试从 PDCurses 获取鼠标位置数据,它通常可以正常工作。问题是,如果在事件检查发生之前鼠标按钮被按下两次,则只会从队列中弹出一个事件。这意味着第二次按下的事件仍在队列中,下一次按下鼠标时,将弹出旧位置而不是最近的位置。如果这种情况持续发生,队列将开始备份,并且报告的鼠标按下次数会越来越少。
因为我唯一使用 getch
的是鼠标事件(我使用 Window 的 GetAsyncKeyState
和我自己的键盘事件管理器),我认为一个简单的解决方法就是在读取鼠标事件后清除事件队列。
不幸的是,它似乎并不那么容易,因为我找不到任何允许清除队列的方法。
我唯一能想到的方法是使用nodelay
将getch
设置为非阻塞,然后重复使用getch
,保留最后一个弹出的事件。不过,这似乎效率低下且不准确。
因为这可能是一个 XY 问题,所以这里是有问题的函数:
void EventHandler::getMousePos(int& x, int& y) {
MEVENT event;
if (nc_getmouse(&event) == OK) {
x = event.x, y = event.y;
}
}
事件处理器.h:
#ifndef EVENT_HANDLER_H
#define EVENT_HANDLER_H
#include <vector>
#include <atomic>
#include <thread>
#include <functional>
#include <windows.h>
#include <WinUser.h>
#include "curses.h"
#define LEFT_MOUSE VK_LBUTTON
#define RIGHT_MOUSE VK_RBUTTON
#define MIDDLE_MOUSE VK_MBUTTON
typedef std::function<void(char)> KeyHandler;
typedef std::function<void(char,long,long)> MouseHandler;
class EventHandler {
std::thread listeningThread;
std::atomic<bool> listening = false;
std::vector<char> keysToCheck;
std::vector<char> mButtonsToCheck;
KeyHandler keyHandler = KeyHandler();
MouseHandler mouseHandler = MouseHandler();
void actOnPressedKeys();
public:
EventHandler();
~EventHandler();
void setKeyHandler(KeyHandler);
void setMouseHandler(MouseHandler);
void setKeysToListenOn(std::vector<char>);
void setButtonsToListenOn(std::vector<char>);
void listenForPresses(int loopMSDelay = 100);
void stopListening();
static void getMousePos(int& x, int& y);
};
#endif
事件处理器.cpp:
#include "EventHandler.h"
#include <thread>
#include <stdexcept>
#include <cctype>
EventHandler::EventHandler() {
}
EventHandler::~EventHandler() {
stopListening();
if (listeningThread.joinable()) {
//May need to fix this. May cause the EventHandler to freeze
// on destruction if listeningThread can't join;
listeningThread.join();
}
}
void EventHandler::actOnPressedKeys() {
for (char key : keysToCheck) {
if (GetAsyncKeyState(key)) {
//pressedKeys.insert(key);
keyHandler(key);
}
}
for (char button : mButtonsToCheck) {
if ( GetAsyncKeyState(button) ) {
int x = 0, y = 0;
getMousePos(x, y);
mvprintw(y, x, "Button Press Detected");
mouseHandler(button, x, y);
}
}
}
/*void EventHandler::actOnPressedKeys() {
pressedKeys.forEach([](char key){
keyHandler(key);
});
}*/
void EventHandler::setKeyHandler(KeyHandler handler) {
keyHandler = handler;
}
void EventHandler::setMouseHandler(MouseHandler handler) {
mouseHandler = handler;
}
void EventHandler::setKeysToListenOn(std::vector<char> newListenKeys) {
if (listening) {
throw std::runtime_error::runtime_error(
"Cannot change the listened-on keys while listening"
);
//This could be changed to killing the thread by setting
// listening to false, changing the keys, then restarting
// the listening thread. I can't see that being necessary though.
}
//Untested
for (char& key : newListenKeys) {
if (key >= 'a' && key <= 'z') {
key += 32;
}
}
keysToCheck = newListenKeys;
}
void EventHandler::setButtonsToListenOn(std::vector<char> newListenButtons) {
if (listening) {
throw std::runtime_error::runtime_error(
"Cannot change the listened-on buttons while listening"
);
}
mButtonsToCheck = newListenButtons;
}
void EventHandler::listenForPresses(int loopMSDelay) {
listening = true;
listeningThread = std::thread ([=]{
do {
actOnPressedKeys();
std::this_thread::sleep_for(std::chrono::milliseconds(loopMSDelay));
} while (listening);
});
}
void EventHandler::stopListening() {
listening = false;
}
void EventHandler::getMousePos(int& x, int& y) {
MEVENT event;
if (nc_getmouse(&event) == OK) {
x = event.x, y = event.y;
}
}
最佳答案
PDCurses 实现了 flushinp
,它应该执行请求的操作。注释和函数(例如,对于 win32)状态
/* discard any pending keyboard or mouse input -- this is the core
routine for flushinp() */
void PDC_flushinp(void)
{
PDC_LOG(("PDC_flushinp() - called\n"));
FlushConsoleInputBuffer(pdc_con_in);
}
顺便说一句,大多数 curses 实现中都提供了这个功能。这是 manual page 的链接在 ncurses 中,这可能会有帮助。
关于c++ - 有什么办法可以清除 Curse 的事件队列吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29921821/
我是一名优秀的程序员,十分优秀!