首页 > 编程语言 >C++ 简易按键精灵制作

C++ 简易按键精灵制作

时间:2022-11-24 16:24:12浏览次数:53  
标签:std && ip void C++ 简易 按键精灵 key include

 简易按键精灵制作

参考链接:https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-sendinput?redirectedfrom=MSDNhttps://www.fluentcpp.com/2018/12/28/timer-cpp/https://github.com/99x/timercpp

具体实现见代码,同时可以设置定时器进行定时操作按键。

按键代码实现(注意必须通过管理员身份运行生成的可执行文件才有效):

 
  #include <iostream>   #include <Windows.h>   #include <tchar.h>       #include "timer.h"       // The reference between key and code connection can be found below:   // https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes           /***************************************************************/   /* 全局定义 */   /***************************************************************/   constexpr size_t ARRAY_MAX_SIZE = 4;           /*****************************************************************   功能描述: 发送按键消息   其他说明:   *******************************************************************/   void GenerateKeyMsg(HWND hwnd, DWORD keyVal)   {   std::cout << "Post message start. -->";   LPARAM lparam = (MapVirtualKey(keyVal, 0) << 16) + 1;   PostMessage(hwnd, WM_KEYDOWN, keyVal, lparam);   std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<size_t>(50)));   PostMessage(hwnd, WM_KEYUP, keyVal, lparam);   std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<size_t>(10)));   std::cout << " Post message finish." << std::endl;   }           int main()   {   std::cout << "Input time interval:" << std::endl;       int delay;   std::cin >> delay;       // 获取MapleStory句柄   auto ms = FindWindow(NULL, _T("MapleStory"));   if (ms == NULL)   {   std::cout << "No game is found." << std::endl;   return 0;   }       // 界面最前显示   if (!SetForegroundWindow(ms))   return 0;       Timer timer;       timer.setInterval(std::bind(GenerateKeyMsg, ms, 0x43), delay);       timer.loop();   return 0;   }
 
 

定时器实现:

 
#include <iostream>   #include <thread>   #include <chrono>   #include <functional>       class Timer   {   bool clear = false;       public:       void setTimeout(std::function<void(void)> func, float delay);       void setInterval(std::function<void(void)> func, float delay);       void stop();       void loop();   };       void Timer::setTimeout(std::function<void(void)> func, float delay)   {   this->clear = false;   std::thread t([=]() {   if (this->clear) return;   std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<size_t>(delay * 1000)));   if (this->clear) return;   func();   });   t.detach();   }       void Timer::setInterval(std::function<void(void)> func, float delay)   {   this->clear = false;   std::thread t([=]() {   while (true)   {   if (this->clear) return;   std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<size_t>(delay * 1000)));   if (this->clear) return;   func();   }   });   t.detach();   }       void Timer::stop()   {   this->clear = true;   }       void Timer::loop()   {   while (!this->clear)   {       }   }
 
 

完善后包含有按键处理的代码,可以使用notepad测试

 
  #include <iostream>   #include <Windows.h>   #include <tchar.h>       #include "timer.h"   #include "input.h"       // The reference between key and code connection can be found below:   // https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes           /***************************************************************/   /* 全局定义 */   /***************************************************************/               /*****************************************************************   功能描述: 发送按键消息   其他说明: 发送给全部窗口   *******************************************************************/   void GenerateKeyMsgForActiveWindow(WORD virKey = 0x41, WORD flag = 0)   {   INPUT ip;       // Set up a generic keyboard event.   ip.type = INPUT_KEYBOARD;   ip.ki.wScan = 0; // hardware scan code for key   ip.ki.time = 0;   ip.ki.dwExtraInfo = 0;       // Press the "A" key   ip.ki.wVk = virKey; // virtual-key code for the "a" key   ip.ki.dwFlags = flag; // 0 for key press   auto uSent = SendInput(1, &ip, sizeof(INPUT));       // Release the "A" key   //ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release   //SendInput(1, &ip, sizeof(INPUT));   if (uSent != 1)   {   std::cout << "[ERROR] Send Key Message failed: " << HRESULT_FROM_WIN32(GetLastError()) << std::endl;   }   }       /*****************************************************************   功能描述: 发送按键消息   其他说明: 发送给单个窗口   *******************************************************************/   void GenerateKeyMsgForInactiveWindow(HWND hwnd, DWORD keyVal)   {   LPARAM lparam = (MapVirtualKey(keyVal, 0) << 16) + 1;   PostMessage(hwnd, WM_KEYDOWN, keyVal, lparam);   std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<size_t>(50)));   PostMessage(hwnd, WM_KEYUP, keyVal, lparam);   std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<size_t>(10)));   // PostMessage(hwnd, WM_CLOSE, NULL, NULL);   // std::cout << GetLastError() << std::endl;   }       /*****************************************************************   功能描述: 主程序入口   其他说明:   *******************************************************************/   int main()   {   Input input;   Timer timer;   bool loop = false;       while (!input.exit())   {   if(!loop)   input.parser();   const auto keyMap = input.getKeyBoard();       auto hwnd = FindWindow(NULL, _T("new 1 - Notepad++ [Administrator]"));   if (hwnd == NULL)   {   std::cout << "[WARN] No Application is Found." << std::endl;   return 0;   }       // 界面最前显示   if (!SetForegroundWindow(hwnd))   return 0;       for (auto& key : keyMap)   {   if (key.first == VK_ESCAPE)   continue;   std::cout << "[INFO] Key Value: " << key.first << " / Time Interval: " << key.second << std::endl;   timer.setInterval(std::bind(GenerateKeyMsgForInactiveWindow, hwnd, key.first), key.second);   }       input.parser();   timer.stop();   loop = true;   }       return 0;   }
 
 
 
  #pragma once       #include <iostream>   #include <string>   #include <map>   #include <WinUser.h>       class Input   {   public:   Input()   {   std::cout << "Please enter the time interval of each key you want " << std::endl   << "and set 'start' value as 1 to start application." << std::endl << std::endl;   }       void parser()   {   std::string line;   while (std::getline(std::cin, line))   {   if (line == "start")   {   break;   }       std::string key, time;   for (size_t pos = 0; pos < line.length(); ++pos)   {   if (pos > 0 && key.empty() && line[pos - 1] != ' ' && line[pos] == ' ')   {   key = line.substr(0, pos);   }       if (pos + 1 < line.length() && time.empty()   && line[pos] == ' ' && line[pos + 1] != ' ' && key != "quit")   {   time = line.substr(pos + 1, line.length() - 1 - pos);   keyBoardRec[ConvertIntoKeyValue(key)] = atof(time.c_str());   }   }   }   }       const std::map<int, float>& getKeyBoard() const {   return keyBoardRec;   }       bool exit() {   return keyBoardRec.find(VK_ESCAPE) != keyBoardRec.end();   }       private:       std::map<int, float> keyBoardRec;       int ConvertIntoKeyValue(const std::string& key)   {   if (key.length() == 1)   {   int off = key[0] - 'a';   if (off >= 0 && off <= 26)   {   return 0x41 + off; /* a */   }       off = key[0] - '0';   if (off >= 0 && off <= 9)   {   return 0x30 + off; /* 0 */   }   }       if (key == "shift")   {   return VK_SHIFT;   }       if (key == "ctrl")   {   return VK_CONTROL;   }       if (key == "alt")   {   return VK_MENU;   }       if (key == "space")   {   return VK_SPACE;   }       if (key == "delete")   {   return VK_DELETE;   }       if (key == "end")   {   return VK_END;   }       if (key == "pagedown")   {   return VK_NEXT;   }       if (key == "pageup")   {   return VK_PRIOR;   }       if (key == "esc")   {   return VK_ESCAPE;   }       return 0x0;   }   };
 
 

 

 

标签:std,&&,ip,void,C++,简易,按键精灵,key,include
From: https://www.cnblogs.com/lidabo/p/16922243.html

相关文章