New file |
| | |
| | | #include "ConfigUtil.h" |
| | | |
| | | #include "ConfigUtil.h" |
| | | #include <iostream> |
| | | #include <fstream> |
| | | |
| | | bool fileExists(const std::string& filename) { |
| | | std::ifstream file(filename); |
| | | return file.good(); // 如果文件成功打开,则返回 true |
| | | } |
| | | |
| | | void ConfigUtil::readConfig(libconfig::Config& config) |
| | | { |
| | | |
| | | string strConfPath = "config.cfg"; |
| | | if (!fileExists(strConfPath)) { |
| | | std::ofstream file(strConfPath); |
| | | file.is_open(); |
| | | } |
| | | |
| | | //解读配置文件 |
| | | try { |
| | | config.readFile(strConfPath.c_str()); |
| | | } |
| | | catch (const libconfig::FileIOException& fioex) { |
| | | std::cerr << "I/O exception while reading the file." << std::endl; |
| | | } |
| | | catch (const libconfig::ParseException& pex) { |
| | | std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() |
| | | << " - " << pex.getError() << std::endl; |
| | | } |
| | | } |
| | | |
| | | void ConfigUtil::writeConfig(libconfig::Config& config) |
| | | { |
| | | config.writeFile("config.cfg"); |
| | | } |
| | | |
| | | int ConfigUtil::readIntConfig(const char* key) |
| | | { |
| | | |
| | | libconfig::Config mConfig; |
| | | readConfig(mConfig); |
| | | libconfig::Setting& root = mConfig.getRoot(); |
| | | if (root.exists(key)) { |
| | | int val; |
| | | root.lookupValue(key, val); |
| | | return val; |
| | | } |
| | | throw string("尚未获取到内容"); |
| | | } |
| | | |
| | | string ConfigUtil::readStringConfig(const char* key) |
| | | { |
| | | libconfig::Config mConfig; |
| | | readConfig(mConfig); |
| | | libconfig::Setting& root = mConfig.getRoot(); |
| | | if (root.exists(key)) { |
| | | //string val; |
| | | const char* val; |
| | | root.lookupValue(key, val); |
| | | return string(val); |
| | | } |
| | | throw string("尚未获取到内容"); |
| | | } |
| | | |
| | | |
| | | |
| | | void ConfigUtil::setIntConfig(const char* key, int val) { |
| | | libconfig::Config mConfig; |
| | | readConfig(mConfig); |
| | | libconfig::Setting& root = mConfig.getRoot(); |
| | | if (root.exists(key)) { |
| | | root[key] = val; |
| | | } |
| | | else { |
| | | root.add(key, libconfig::Setting::TypeInt) = val; |
| | | } |
| | | writeConfig(mConfig); |
| | | } |
| | | void ConfigUtil::setStringConfig(const char* key, string val) { |
| | | libconfig::Config mConfig; |
| | | readConfig(mConfig); |
| | | libconfig::Setting& root = mConfig.getRoot(); |
| | | if (root.exists(key)) { |
| | | root[key] = val.c_str(); |
| | | } |
| | | else { |
| | | root.add(key, libconfig::Setting::TypeString) = val.c_str(); |
| | | } |
| | | writeConfig(mConfig); |
| | | } |
| | | |
| | | list<string> ConfigUtil::getKeys() |
| | | { |
| | | libconfig::Config mConfig; |
| | | readConfig(mConfig); |
| | | libconfig::Setting& root = mConfig.getRoot(); |
| | | list<string> keys; |
| | | for (auto iter = root.begin(); iter != root.end(); ++iter) { |
| | | keys.push_back(iter->getName()); |
| | | } |
| | | return keys; |
| | | } |
| | | |
| | | void ConfigUtil::delKey(string key) |
| | | { |
| | | libconfig::Config mConfig; |
| | | readConfig(mConfig); |
| | | libconfig::Setting& root = mConfig.getRoot(); |
| | | root.remove(key); |
| | | } |
New file |
| | |
| | | #pragma once |
| | | #include<string> |
| | | #include <libconfig.h++> |
| | | #include<list> |
| | | using namespace std; |
| | | class ConfigUtil |
| | | { |
| | | private: |
| | | static void readConfig(libconfig::Config& config); |
| | | static void writeConfig(libconfig::Config& config); |
| | | |
| | | |
| | | protected: |
| | | static int readIntConfig(const char* key); |
| | | static string readStringConfig(const char* key); |
| | | static void setIntConfig(const char* key, int val); |
| | | static void setStringConfig(const char* key, string val); |
| | | static list<string> getKeys(); |
| | | static void delKey(string key); |
| | | }; |
| | | |
New file |
| | |
| | | #pragma once |
| | | #include <string> |
| | | #include <list> |
| | | #include <set> |
| | | #include "StringUtil.h" |
| | | #include "rapidjson/document.h" |
| | | #include "rapidjson/writer.h" |
| | | #include "rapidjson/stringbuffer.h" |
| | | #include <rapidjson/prettywriter.h> |
| | | |
| | | using namespace std; |
| | | |
| | | class JsonUtil { |
| | | public: |
| | | static rapidjson::Document parseUTF8(string src) { |
| | | rapidjson::Document root; |
| | | root.Parse(src.c_str()); |
| | | return root; |
| | | } |
| | | |
| | | static rapidjson::GenericDocument<rapidjson::UTF16<>> parseUTF16(string src) { |
| | | wstring wresult = StringUtil::Unescape(src); |
| | | rapidjson::GenericDocument<rapidjson::UTF16<>> root; |
| | | root.Parse(wresult.c_str()); |
| | | return root; |
| | | } |
| | | |
| | | static string toJsonStr(rapidjson::Document& document) { |
| | | rapidjson::StringBuffer buffer; |
| | | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); |
| | | document.Accept(writer); |
| | | std::string jsonString = buffer.GetString(); |
| | | return jsonString; |
| | | } |
| | | |
| | | |
| | | }; |
New file |
| | |
| | | #include "NetworkApi.h" |
| | | #include <chrono> |
| | | #include <random> |
| | | #include "md5.h" |
| | | #include "SocketManager.h" |
| | | |
| | | string NetworkApi::_TRADE_SERVER_ADDR ="43.138.167.68"; |
| | | int NetworkApi::_TRADE_SERVER_PORT = 11008; |
| | | string NetworkApi::_COMMON_SERVER_ADDR; |
| | | int NetworkApi::_COMMON_SERVER_PORT; |
| | | |
| | | string NetworkApi::get_rquest_id() |
| | | { |
| | | string requestIdStr; |
| | | std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); |
| | | // 将当前时间点转换为time_t类型 |
| | | std::time_t currentTime = std::chrono::system_clock::to_time_t(now); |
| | | requestIdStr.append("_").append(std::to_string(currentTime)).append("_"); |
| | | // 生成随机数 |
| | | std::random_device rd; |
| | | std::mt19937 rng(rd()); |
| | | std::uniform_int_distribution<int> intDist(1, 100000); // 生成范围在1-100之间的整数 |
| | | int randomInt = intDist(rng); |
| | | requestIdStr.append(std::to_string(randomInt)); |
| | | return requestIdStr; |
| | | } |
| | | |
| | | string NetworkApi::get_sign(rapidjson::Document& document) |
| | | { |
| | | //计算签名 |
| | | std::list<string> strList; |
| | | for (rapidjson::Value::ConstMemberIterator itr = document.MemberBegin(); itr != document.MemberEnd(); ++itr) { |
| | | if (itr->value.IsObject() || itr->value.IsArray()) { |
| | | //如果是对象 |
| | | rapidjson::StringBuffer buffer; |
| | | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); |
| | | itr->value.Accept(writer); |
| | | std::string jsonString = buffer.GetString(); |
| | | strList.push_back(string(itr->name.GetString()).append("=").append(jsonString)); |
| | | } |
| | | else { |
| | | if (itr->value.IsString()) { |
| | | strList.push_back(string(itr->name.GetString()).append("=").append(itr->value.GetString())); |
| | | } |
| | | else if (itr->value.IsInt()) { |
| | | strList.push_back(string(itr->name.GetString()).append("=").append(std::to_string(itr->value.GetInt()))); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | strList.sort(); |
| | | strList.push_back("%Yeshi2014@#."); |
| | | string src = ""; |
| | | int index = 0; |
| | | for (std::list<string>::iterator el = strList.begin(); el != strList.end(); el++) { |
| | | src.append(*el); |
| | | index++; |
| | | if (index != strList.size()) { |
| | | src.append("&"); |
| | | } |
| | | } |
| | | //MD5 |
| | | //cout << "加密前字符串:" <<src << endl; |
| | | string md5 = MD5(src).toStr(); |
| | | return md5; |
| | | } |
| | | |
| | | |
| | | void NetworkApi::set_server_info(string trade_addr, int trade_port, string common_addr, int common_port) |
| | | { |
| | | _TRADE_SERVER_ADDR = trade_addr; |
| | | _TRADE_SERVER_PORT = trade_port; |
| | | _COMMON_SERVER_ADDR = common_addr; |
| | | _COMMON_SERVER_PORT = common_port; |
| | | } |
| | | |
| | | std::string NetworkApi::load_request_data(std::string data) |
| | | { |
| | | rapidjson::Document document; |
| | | document.Parse(data.c_str()); |
| | | string requestIdStr = (document["type"].IsInt() ? std::to_string(document["type"].GetInt()) : document["type"].GetString()).append(get_rquest_id()); |
| | | rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); |
| | | |
| | | // 添加 request_id 字段 |
| | | rapidjson::Value requestId(rapidjson::kStringType); |
| | | requestId.SetString(requestIdStr.c_str(), allocator); |
| | | document.AddMember("request_id", requestId, allocator); |
| | | // 添加签名,sign |
| | | string sign = get_sign(document); |
| | | rapidjson::Value signV(rapidjson::kStringType); |
| | | signV.SetString(sign.c_str(), allocator); |
| | | document.AddMember("sign", signV, allocator); |
| | | |
| | | rapidjson::StringBuffer buffer; |
| | | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); |
| | | document.Accept(writer); |
| | | |
| | | std::string jsonString = buffer.GetString(); |
| | | //发送数据 |
| | | std::stringstream ss; |
| | | ss << std::setw(8) << std::setfill('0') << jsonString.length(); |
| | | std::string length_str = string("##").append(ss.str()); |
| | | std::string fstr = length_str.append(jsonString); |
| | | return fstr; |
| | | } |
| | | |
| | | |
| | | //网络请求 |
| | | std::string NetworkApi::base_request(std::string data) { |
| | | std::string fstr = load_request_data(data); |
| | | try { |
| | | return SocketManager::sendMsg(_COMMON_SERVER_ADDR, _COMMON_SERVER_PORT, fstr.c_str()); |
| | | } |
| | | catch (...) { |
| | | throw L"网络请求出错"; |
| | | } |
| | | } |
| | | |
| | | std::string NetworkApi::base_trade_request(std::string data) |
| | | { |
| | | rapidjson::Document document; |
| | | document.Parse(data.c_str()); |
| | | string requestIdStr = string(document["type"].GetString()).append(get_rquest_id()); |
| | | rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); |
| | | |
| | | // 添加 request_id 字段 |
| | | rapidjson::Value requestId(rapidjson::kStringType); |
| | | requestId.SetString(requestIdStr.c_str(), allocator); |
| | | document.AddMember("request_id", requestId, allocator); |
| | | // 添加签名,sign |
| | | string sign = get_sign(document); |
| | | rapidjson::Value signV(rapidjson::kStringType); |
| | | signV.SetString(sign.c_str(), allocator); |
| | | document.AddMember("sign", signV, allocator); |
| | | |
| | | rapidjson::StringBuffer buffer; |
| | | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); |
| | | document.Accept(writer); |
| | | |
| | | std::string jsonString = buffer.GetString(); |
| | | //发送数据 |
| | | std::stringstream ss; |
| | | ss << std::setw(8) << std::setfill('0') << jsonString.length(); |
| | | std::string length_str = string("##").append(ss.str()); |
| | | std::string fstr = length_str.append(jsonString); |
| | | |
| | | try { |
| | | return SocketManager::sendMsg(_TRADE_SERVER_ADDR, _TRADE_SERVER_PORT, fstr.c_str()); |
| | | } |
| | | catch (...) { |
| | | throw wstring(L"网络请求出错"); |
| | | } |
| | | } |
New file |
| | |
| | | #pragma once |
| | | #include <string> |
| | | #include <list> |
| | | #include "JsonUtil.h" |
| | | using namespace std; |
| | | class NetworkApi |
| | | { |
| | | protected: |
| | | static string _TRADE_SERVER_ADDR; |
| | | static int _TRADE_SERVER_PORT; |
| | | static string _COMMON_SERVER_ADDR; |
| | | static int _COMMON_SERVER_PORT; |
| | | |
| | | |
| | | // 网络请求 |
| | | static std::string base_request(std::string data); |
| | | // 请求交易服务器 |
| | | static std::string base_trade_request(std::string data); |
| | | static string get_rquest_id(); |
| | | static string get_sign(rapidjson::Document& document); |
| | | public: |
| | | |
| | | static void set_server_info(string trade_addr,int trade_port, string common_addr,int common_port); |
| | | |
| | | static std::string load_request_data(std::string data); |
| | | |
| | | |
| | | |
| | | }; |
| | | |
New file |
| | |
| | | #include "SocketManager.h" |
| | | #include <string> |
| | | |
| | | #define _WINSOCK_DEPRECATED_NO_WARNINGS 1 |
| | | |
| | | |
| | | |
| | | string SocketManager::ADDR; |
| | | |
| | | |
| | | SocketManager::~SocketManager() { |
| | | |
| | | } |
| | | |
| | | |
| | | string SocketManager::sendMsg(const char* msg) { |
| | | ADDR = "43.138.167.68"; |
| | | //ADDR = "192.168.3.122"; |
| | | return SocketManager::sendMsg(ADDR, PORT, msg); |
| | | } |
| | | |
| | | string SocketManager::sendMsg(string addr, int port, const char* msg) { |
| | | WSADATA wsd; |
| | | WSAStartup(MAKEWORD(2, 2), &wsd); |
| | | SOCKET m_SockClient; |
| | | m_SockClient = socket(AF_INET, SOCK_STREAM, 0); |
| | | sockaddr_in clientaddr; |
| | | clientaddr.sin_family = AF_INET; |
| | | clientaddr.sin_port = htons(port); |
| | | //clientaddr.sin_addr.S_un.S_addr = ; |
| | | inet_pton(AF_INET, addr.c_str(), &clientaddr.sin_addr); |
| | | |
| | | connect(m_SockClient, (sockaddr*)&clientaddr, sizeof(clientaddr)); |
| | | char buffer[1024]; |
| | | |
| | | int result = send(m_SockClient, msg, strlen(msg), 0); |
| | | if (result < 0) { |
| | | throw string("发送失败"); |
| | | } |
| | | int header_length = 10; |
| | | int num = recv(m_SockClient, buffer, 1024, 0); |
| | | string data = string(buffer, 0, num); |
| | | if (data.find("##") == 0) { |
| | | //带有头文件 |
| | | int count = std::stoi(data.substr(2, header_length - 2)); |
| | | data = data.substr(header_length); |
| | | while (data.length() < count) { |
| | | char buffer[1024]; |
| | | num = recv(m_SockClient, buffer, 1024, 0); |
| | | if (num > 0) { |
| | | data.append(string(buffer, 0, num)); |
| | | } |
| | | } |
| | | } |
| | | closesocket(m_SockClient); |
| | | if (num < 0) { |
| | | throw string("未接收到信息"); |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | string SocketManager::sendMsg(SOCKET m_SockClient, const char* msg) |
| | | { |
| | | char buffer[1024]; |
| | | int result = send(m_SockClient, msg, strlen(msg), 0); |
| | | if (result < 0) { |
| | | throw string("发送失败"); |
| | | } |
| | | int header_length = 10; |
| | | int num = recv(m_SockClient, buffer, 1024, 0); |
| | | string data = string(buffer, 0, num); |
| | | if (data.find("##") == 0) { |
| | | //带有头文件 |
| | | int count = std::stoi(data.substr(2, header_length - 2)); |
| | | data = data.substr(header_length); |
| | | while (data.length() < count) { |
| | | char buffer[1024]; |
| | | num = recv(m_SockClient, buffer, 1024, 0); |
| | | if (num > 0) { |
| | | data.append(string(buffer, 0, num)); |
| | | } |
| | | } |
| | | } |
| | | if (num < 0) { |
| | | throw string("未接收到信息"); |
| | | } |
| | | return data; |
| | | } |
| | | |
| | | SOCKET SocketManager::createSocket(string addr, int port) |
| | | { |
| | | WSADATA wsd; |
| | | WSAStartup(MAKEWORD(2, 2), &wsd); |
| | | SOCKET m_SockClient; |
| | | m_SockClient = socket(AF_INET, SOCK_STREAM, 0); |
| | | sockaddr_in clientaddr; |
| | | clientaddr.sin_family = AF_INET; |
| | | clientaddr.sin_port = htons(port); |
| | | //clientaddr.sin_addr.S_un.S_addr = ; |
| | | inet_pton(AF_INET, addr.c_str(), &clientaddr.sin_addr); |
| | | |
| | | int c = connect(m_SockClient, (sockaddr*)&clientaddr, sizeof(clientaddr)); |
| | | if (c != 0) { |
| | | throw string("socket连接失败"); |
| | | } |
| | | return m_SockClient; |
| | | } |
| | | |
| | | string SocketManager::receiveMsg(SOCKET m_SockClient) |
| | | { |
| | | char buffer[1024]; |
| | | int header_length = 10; |
| | | int num = recv(m_SockClient, buffer, 1024, 0); |
| | | if (num <= 0) { |
| | | throw string("连接已断开"); |
| | | } |
| | | string data = string(buffer, 0, num); |
| | | if (data.find("##") == 0) { |
| | | //带有头文件 |
| | | int count = std::stoi(data.substr(2, header_length - 2)); |
| | | data = data.substr(header_length); |
| | | while (data.length() < count) { |
| | | char buffer[1024]; |
| | | num = recv(m_SockClient, buffer, 1024, 0); |
| | | if (num > 0) { |
| | | data.append(string(buffer, 0, num)); |
| | | } |
| | | } |
| | | } |
| | | return data; |
| | | } |
New file |
| | |
| | | #pragma once |
| | | #include<WinSock2.h> |
| | | #include <WS2tcpip.h> |
| | | #pragma comment(lib,"ws2_32.lib") |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | #include <list> |
| | | #include <iostream> |
| | | #include <atlstr.h> |
| | | // B类 |
| | | #define MAIN_HOST "43.138.167.68" |
| | | #define API_PORT 11008 |
| | | //A 类 |
| | | //#define API_PORT 11009 |
| | | using namespace std; |
| | | class SocketManager |
| | | { |
| | | private: |
| | | static const int PORT = API_PORT; |
| | | sockaddr_in clientaddr; |
| | | |
| | | |
| | | public: |
| | | static string ADDR; |
| | | static const int OCR_PORT = 9002; |
| | | ~SocketManager(); |
| | | static string sendMsg(const char*); |
| | | static string sendMsg(string addr, int port, const char*); |
| | | static string sendMsg(SOCKET socket, const char*); |
| | | static SOCKET createSocket(string addr = MAIN_HOST, int port = API_PORT); |
| | | // 接收消息 |
| | | static string receiveMsg(SOCKET socket); |
| | | }; |
| | | |
| | | |
New file |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <string> |
| | | #include <locale> |
| | | #include <codecvt> |
| | | #include <iostream> |
| | | #include <sstream> |
| | | #include <iomanip> |
| | | #include <vector> |
| | | using namespace std; |
| | | |
| | | class StringUtil { |
| | | |
| | | public: |
| | | static string wstringToString(wstring wt) { |
| | | wstring_convert<codecvt_utf8<wchar_t>> conv; |
| | | string result = conv.to_bytes(wt); |
| | | return result; |
| | | } |
| | | |
| | | static std::wstring Unescape(const std::string& input) { |
| | | std::wstring wresult; |
| | | for (size_t i = 0; i < input.length(); ) { |
| | | if (input[i] == '\\' && input[i + 1] == 'u') { |
| | | std::string code = input.substr(i + 2, 4); |
| | | wchar_t unicode = stoi(code, nullptr, 16); |
| | | wresult += unicode; |
| | | i += 6; |
| | | } |
| | | else { |
| | | wresult += input[i++]; |
| | | } |
| | | } |
| | | return wresult; |
| | | } |
| | | |
| | | |
| | | static string to_string(double val) { |
| | | std::stringstream stream; |
| | | stream << std::fixed << std::setprecision(2) << val; |
| | | return stream.str(); |
| | | } |
| | | |
| | | static bool isNumber(const std::string& str) { |
| | | if (str.empty()) { |
| | | return false; |
| | | } |
| | | for (char c : str) { |
| | | if (!isdigit(c)) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | // double转为字符串 |
| | | static string toString(double value, int precision) { |
| | | std::ostringstream oss; |
| | | oss << std::fixed << std::setprecision(precision) << value; |
| | | return oss.str(); |
| | | } |
| | | |
| | | static std::vector<std::string> split(std::string str, std::string pattern) { |
| | | std::string::size_type pos; |
| | | std::vector<std::string> result; |
| | | str += pattern;//扩展字符串以方便操作 |
| | | int size = str.size(); |
| | | for (int i = 0; i < size; i++) |
| | | { |
| | | pos = str.find(pattern, i); |
| | | if (pos < size) |
| | | { |
| | | std::string s = str.substr(i, pos - i); |
| | | result.push_back(s); |
| | | i = pos + pattern.size() - 1; |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | }; |
New file |
| | |
| | | #pragma once |
| | | #include <chrono> |
| | | class TimeUtil { |
| | | |
| | | public: |
| | | // 获取当前时间戳 |
| | | static UINT16 getNowTimeStamp() { |
| | | auto now = std::chrono::system_clock::now(); |
| | | // 转换为时间戳 |
| | | auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now); |
| | | // 获取时间戳值 |
| | | auto value = now_ms.time_since_epoch().count(); |
| | | return value; |
| | | } |
| | | |
| | | |
| | | }; |
New file |
| | |
| | | #include "WidgetsRenderUtil.h" |
| | | #include <map> |
| | | using namespace std; |
| | | |
| | | // 绘制内容信息 |
| | | struct TextDrawInfo |
| | | { |
| | | wxRect rect;//绘制的区域 |
| | | wxColour color;// 绘制的颜色 |
| | | wxString text;// 内容 |
| | | }; |
| | | |
| | | // 行信息 |
| | | struct LineInfo { |
| | | int start_index; |
| | | int end_index; |
| | | }; |
| | | |
| | | int WidgetsRenderUtil::drawText(wxDC* dc, wxString st, wxPoint startP, int lineWidth, int lineHeight, std::list<ColorIndexInfo> colors , wxColour defaultColor) { |
| | | ///绘制可局部变色,可换行的富文本,返回高度 |
| | | /// 实现思路:1.先根据整体控件宽度或者换行符换行,确定行数 |
| | | /// 2.根据颜色的索引,确定绘制内容的文本,颜色,位置 |
| | | /// 3.根据第2步得到的数据,加上整个控件偏移量统一绘制文本内容 |
| | | |
| | | // 计算是否需要换行 |
| | | wxString line_text; |
| | | std::list<LineInfo> lines; |
| | | |
| | | |
| | | int start_index = -1; |
| | | for (int i = 0; i < st.length(); i++) { |
| | | line_text.Append(st.GetChar(i)); |
| | | // 计算绘制文本占用的尺寸 |
| | | wxSize textSize = dc->GetTextExtent(line_text); |
| | | if (start_index < 0 ) { |
| | | start_index = i; |
| | | } |
| | | |
| | | int nextCharWidth = 0; |
| | | if (i + 1 < st.Length()) { |
| | | // 获取下一个字符的长度 |
| | | wxSize textSize1 = dc->GetTextExtent(st.GetChar(i+1)); |
| | | nextCharWidth = textSize1.GetWidth(); |
| | | } |
| | | |
| | | |
| | | if (textSize.GetWidth() + nextCharWidth > lineWidth) { |
| | | lines.push_back(LineInfo({ start_index, i })); |
| | | start_index = -1; |
| | | line_text = ""; |
| | | } |
| | | else if (st.GetChar(i) == '\n') { |
| | | lines.push_back(LineInfo({ start_index, i })); |
| | | start_index = -1; |
| | | line_text = ""; |
| | | } |
| | | } |
| | | if (start_index >= 0) { |
| | | lines.push_back(LineInfo({ start_index, (int)st.length() - 1 })); |
| | | start_index = -1; |
| | | } |
| | | |
| | | |
| | | map<int, ColorIndexInfo> colorIndexMap; |
| | | for (list<ColorIndexInfo>::iterator e = colors.begin(); e != colors.end(); ++e) { |
| | | colorIndexMap[(*e).start_index] = *e; |
| | | colorIndexMap[(*e).end_index] = *e; |
| | | } |
| | | |
| | | list<TextDrawInfo> drawInfoList; |
| | | |
| | | int row = 0; |
| | | wxColor color = defaultColor; // 默认颜色为黑色 |
| | | |
| | | for (list<LineInfo>::iterator e = lines.begin(); e != lines.end(); ++e) { |
| | | LineInfo lineInfo = *e; |
| | | // 内容开始 |
| | | int content_start_index = -1; |
| | | int positionLeft = 0; |
| | | for (int i = lineInfo.start_index; i <= lineInfo.end_index; i++) { |
| | | if (content_start_index < 0) { |
| | | content_start_index = i; |
| | | } |
| | | |
| | | // 绘制触发:一行结束,颜色开始,颜色结束 |
| | | if (colorIndexMap.find(i) != colorIndexMap.end()) { |
| | | // 有颜色索引 |
| | | ColorIndexInfo info = colorIndexMap[i]; |
| | | if (info.start_index == i) { |
| | | // 颜色开始,将之前的数据加入绘制 |
| | | if (i > content_start_index) { |
| | | TextDrawInfo drawInfo; |
| | | drawInfo.text = st.Mid(content_start_index, i - content_start_index); |
| | | drawInfo.color = color; |
| | | wxSize ts = dc->GetTextExtent(drawInfo.text); |
| | | drawInfo.rect = wxRect(positionLeft, row * lineHeight, ts.GetWidth(), lineHeight); |
| | | drawInfoList.push_back(drawInfo); |
| | | // 起始点 |
| | | content_start_index = i; |
| | | positionLeft += ts.GetWidth(); |
| | | } |
| | | color = info.color; |
| | | } |
| | | |
| | | if (info.end_index == i) { |
| | | //颜色结束 |
| | | TextDrawInfo drawInfo; |
| | | drawInfo.text = st.Mid(content_start_index, i - content_start_index + 1); |
| | | drawInfo.color = color; |
| | | wxSize ts = dc->GetTextExtent(drawInfo.text); |
| | | drawInfo.rect = wxRect(positionLeft, row * lineHeight, ts.GetWidth(), lineHeight); |
| | | drawInfoList.push_back(drawInfo); |
| | | // 起始点 |
| | | content_start_index = -1; |
| | | positionLeft += ts.GetWidth(); |
| | | //恢复默认颜色 |
| | | color = defaultColor; |
| | | } |
| | | } |
| | | |
| | | if (i == lineInfo.end_index) { |
| | | // 一行结束 |
| | | TextDrawInfo drawInfo; |
| | | drawInfo.text = st.Mid(content_start_index, i - content_start_index + 1); |
| | | drawInfo.color = color; |
| | | wxSize ts = dc->GetTextExtent(drawInfo.text); |
| | | drawInfo.rect = wxRect(positionLeft, row * lineHeight, ts.GetWidth(), lineHeight); |
| | | drawInfoList.push_back(drawInfo); |
| | | } |
| | | } |
| | | row++; |
| | | } |
| | | for (list<TextDrawInfo>::iterator e = drawInfoList.begin(); e != drawInfoList.end(); ++e) { |
| | | TextDrawInfo drawInfo = *e; |
| | | dc->SetTextForeground(drawInfo.color); |
| | | wxRect rect = drawInfo.rect; |
| | | rect.x += startP.x; |
| | | rect.y += startP.y; |
| | | dc->DrawLabel(drawInfo.text, rect, wxALIGN_LEFT | wxALIGN_TOP); |
| | | } |
| | | |
| | | return lines.size() * lineHeight; |
| | | |
| | | } |
| | | |
| | | int WidgetsRenderUtil::drawText(wxGraphicsContext* gc, wxString st, wxPoint startP, int lineWidth, int lineHeight, std::list<ColorIndexInfo> colors, wxColour defaultColor) |
| | | { |
| | | |
| | | ///绘制可局部变色,可换行的富文本,返回高度 |
| | | /// 实现思路:1.先根据整体控件宽度或者换行符换行,确定行数 |
| | | /// 2.根据颜色的索引,确定绘制内容的文本,颜色,位置 |
| | | /// 3.根据第2步得到的数据,加上整个控件偏移量统一绘制文本内容 |
| | | |
| | | // 计算是否需要换行 |
| | | wxString line_text; |
| | | std::list<LineInfo> lines; |
| | | |
| | | |
| | | int start_index = -1; |
| | | for (int i = 0; i < st.length(); i++) { |
| | | line_text.Append(st.GetChar(i)); |
| | | // 计算绘制文本占用的尺寸 |
| | | wxDouble width, height; |
| | | gc->GetTextExtent(line_text, &width,&height); |
| | | wxSize textSize(width, height); |
| | | if (start_index < 0) { |
| | | start_index = i; |
| | | } |
| | | |
| | | int nextCharWidth = 0; |
| | | if (i + 1 < st.Length()) { |
| | | // 获取下一个字符的长度 |
| | | wxDouble width, height; |
| | | gc->GetTextExtent(st.GetChar(i + 1), &width, &height); |
| | | wxSize textSize1(width, height); |
| | | |
| | | |
| | | nextCharWidth = textSize1.GetWidth(); |
| | | } |
| | | |
| | | |
| | | if (textSize.GetWidth() + nextCharWidth > lineWidth) { |
| | | lines.push_back(LineInfo({ start_index, i })); |
| | | start_index = -1; |
| | | line_text = ""; |
| | | } |
| | | else if (st.GetChar(i) == '\n') { |
| | | lines.push_back(LineInfo({ start_index, i })); |
| | | start_index = -1; |
| | | line_text = ""; |
| | | } |
| | | } |
| | | if (start_index >= 0) { |
| | | lines.push_back(LineInfo({ start_index, (int)st.length() - 1 })); |
| | | start_index = -1; |
| | | } |
| | | |
| | | |
| | | map<int, ColorIndexInfo> colorIndexMap; |
| | | for (list<ColorIndexInfo>::iterator e = colors.begin(); e != colors.end(); ++e) { |
| | | colorIndexMap[(*e).start_index] = *e; |
| | | colorIndexMap[(*e).end_index] = *e; |
| | | } |
| | | |
| | | list<TextDrawInfo> drawInfoList; |
| | | |
| | | int row = 0; |
| | | wxColor color = defaultColor; // 默认颜色为黑色 |
| | | |
| | | for (list<LineInfo>::iterator e = lines.begin(); e != lines.end(); ++e) { |
| | | LineInfo lineInfo = *e; |
| | | // 内容开始 |
| | | int content_start_index = -1; |
| | | int positionLeft = 0; |
| | | for (int i = lineInfo.start_index; i <= lineInfo.end_index; i++) { |
| | | if (content_start_index < 0) { |
| | | content_start_index = i; |
| | | } |
| | | |
| | | // 绘制触发:一行结束,颜色开始,颜色结束 |
| | | if (colorIndexMap.find(i) != colorIndexMap.end()) { |
| | | // 有颜色索引 |
| | | ColorIndexInfo info = colorIndexMap[i]; |
| | | if (info.start_index == i) { |
| | | // 颜色开始,将之前的数据加入绘制 |
| | | if (i > content_start_index) { |
| | | TextDrawInfo drawInfo; |
| | | drawInfo.text = st.Mid(content_start_index, i - content_start_index); |
| | | drawInfo.color = color; |
| | | wxDouble width, height; |
| | | gc->GetTextExtent(drawInfo.text, &width, &height); |
| | | wxSize ts(width, height); |
| | | |
| | | drawInfo.rect = wxRect(positionLeft, row * lineHeight, ts.GetWidth(), lineHeight); |
| | | drawInfoList.push_back(drawInfo); |
| | | // 起始点 |
| | | content_start_index = i; |
| | | positionLeft += ts.GetWidth(); |
| | | } |
| | | color = info.color; |
| | | } |
| | | |
| | | if (info.end_index == i) { |
| | | //颜色结束 |
| | | TextDrawInfo drawInfo; |
| | | drawInfo.text = st.Mid(content_start_index, i - content_start_index + 1); |
| | | drawInfo.color = color; |
| | | wxDouble width, height; |
| | | gc->GetTextExtent(drawInfo.text, &width, &height); |
| | | wxSize ts(width, height); |
| | | |
| | | |
| | | drawInfo.rect = wxRect(positionLeft, row * lineHeight, ts.GetWidth(), lineHeight); |
| | | drawInfoList.push_back(drawInfo); |
| | | // 起始点 |
| | | content_start_index = -1; |
| | | positionLeft += ts.GetWidth(); |
| | | //恢复默认颜色 |
| | | color = defaultColor; |
| | | } |
| | | } |
| | | |
| | | if (i == lineInfo.end_index) { |
| | | // 一行结束 |
| | | TextDrawInfo drawInfo; |
| | | drawInfo.text = st.Mid(content_start_index, i - content_start_index + 1); |
| | | drawInfo.color = color; |
| | | |
| | | |
| | | wxDouble width, height; |
| | | gc->GetTextExtent(drawInfo.text, &width, &height); |
| | | wxSize ts(width, height); |
| | | |
| | | |
| | | drawInfo.rect = wxRect(positionLeft, row * lineHeight, ts.GetWidth(), lineHeight); |
| | | drawInfoList.push_back(drawInfo); |
| | | } |
| | | } |
| | | row++; |
| | | } |
| | | for (list<TextDrawInfo>::iterator e = drawInfoList.begin(); e != drawInfoList.end(); ++e) { |
| | | TextDrawInfo drawInfo = *e; |
| | | gc->SetPen(drawInfo.color); |
| | | wxRect rect = drawInfo.rect; |
| | | rect.x += startP.x; |
| | | rect.y += startP.y; |
| | | gc->DrawText(drawInfo.text, rect.x, rect.y); |
| | | } |
| | | |
| | | return lines.size() * lineHeight; |
| | | |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void WidgetsRenderUtil::drawBtn(wxDC* dc, wxString st, wxRect rect, wxColour textColor, wxColour bgColor) |
| | | { |
| | | // 绘制按钮 |
| | | dc->SetPen(bgColor); |
| | | dc->SetBrush(bgColor); |
| | | dc->SetTextForeground(textColor); |
| | | dc->DrawRectangle(rect); |
| | | // 绘制按钮的文本 |
| | | dc->DrawLabel(st, rect, wxALIGN_CENTER); |
| | | } |
| | | |
| | | void WidgetsRenderUtil::drawBtnByGC(wxGraphicsContext* gc, wxString st, wxRect rect, wxColour textColor, wxColour bgColor) |
| | | { |
| | | |
| | | // 绘制按钮 |
| | | gc->SetPen(bgColor); |
| | | gc->SetBrush(wxBrush(bgColor)); |
| | | gc->DrawRectangle(rect.x,rect.y,rect.width,rect.height); |
| | | // 绘制按钮的文本 |
| | | wxDouble width, height; |
| | | gc->GetTextExtent(st, &width, &height); |
| | | gc->SetPen(textColor); |
| | | gc->SetBrush(wxBrush(textColor)); |
| | | gc->DrawText(st, rect.x + (rect.width - width)/2, rect.y + (rect.height - height) / 2); |
| | | } |
New file |
| | |
| | | #pragma once |
| | | #include <wx/wx.h> |
| | | #include <wx/listctrl.h> |
| | | #include <wx/dataview.h> |
| | | #include <list> |
| | | #include <wx/graphics.h> |
| | | |
| | | |
| | | |
| | | |
| | | struct ColorIndexInfo |
| | | { |
| | | int start_index; |
| | | int end_index; |
| | | wxColour color; |
| | | }; |
| | | |
| | | |
| | | |
| | | class WidgetsRenderUtil { |
| | | public: |
| | | // 绘制文本内容 |
| | | static int drawText(wxDC* dc, wxString st, wxPoint startP, int lineWidth, int lineHeight, std::list<ColorIndexInfo> colors = std::list<ColorIndexInfo>(), wxColour defaultColor = *wxBLACK); |
| | | |
| | | static int drawText(wxGraphicsContext* gc, wxString st, wxPoint startP, int lineWidth, int lineHeight, std::list<ColorIndexInfo> colors = std::list<ColorIndexInfo>(), wxColour defaultColor = *wxBLACK); |
| | | |
| | | // 绘制按钮 |
| | | static void drawBtn(wxDC* dc, wxString st, wxRect rect,wxColour textColor, wxColour bgColor); |
| | | |
| | | // 绘制按钮 |
| | | static void drawBtnByGC(wxGraphicsContext* gc, wxString st, wxRect rect, wxColour textColor, wxColour bgColor); |
| | | |
| | | |
| | | |
| | | }; |
New file |
| | |
| | | #include "Win32Util.h" |
| | | #include <thread> |
| | | #include <vector> |
| | | #include "Win32Util.h" |
| | | |
| | | void clickRunner(int delay) // 函数名字可随意 |
| | | { |
| | | Sleep(delay); |
| | | mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); |
| | | Sleep(10); |
| | | mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); |
| | | Sleep(10); |
| | | } |
| | | |
| | | void moveRunner(int x, int y, int delay) // 函数名字可随意 |
| | | { |
| | | Sleep(delay); |
| | | SetCursorPos(x, y); |
| | | Sleep(20); |
| | | } |
| | | |
| | | |
| | | void kbNumRunner(string nums, int delay) // 函数名字可随意 |
| | | { |
| | | Sleep(delay); |
| | | for (int i = 0; i < nums.length(); i++) |
| | | { |
| | | int code = int(nums.c_str()[i]); |
| | | if (code == '.') |
| | | { |
| | | code = 110; |
| | | } |
| | | keybd_event(code, 0, 0, 0); |
| | | Sleep(5); |
| | | keybd_event(code, 0, KEYEVENTF_KEYUP, 0); |
| | | Sleep(20); |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | void kbKeyRunner(int code, int delay) // 函数名字可随意 |
| | | { |
| | | Sleep(delay); |
| | | keybd_event(code, 0, 0, 0); |
| | | keybd_event(code, 0, KEYEVENTF_KEYUP, 0); |
| | | } |
| | | |
| | | std::string Win32Util::convertLPWSTRToUTF8(LPWSTR lpwstr) { |
| | | int len = WideCharToMultiByte(CP_UTF8, 0, lpwstr, -1, NULL, 0, NULL, NULL); |
| | | if (len == 0) { |
| | | // 转换失败 |
| | | return ""; |
| | | } |
| | | char* buffer = new char[len]; |
| | | WideCharToMultiByte(CP_UTF8, 0, lpwstr, -1, buffer, len, NULL, NULL); |
| | | std::string result(buffer); |
| | | delete[] buffer; |
| | | return result; |
| | | } |
| | | |
| | | |
| | | list<HWND> Win32Util::searchWindow(string name) { |
| | | auto hwnd = GetDesktopWindow(); |
| | | HWND mainPage = HWND(); |
| | | //获取桌面子窗口句柄 |
| | | hwnd = GetWindow(hwnd, GW_CHILD); |
| | | list<HWND> list; |
| | | while (hwnd != NULL) |
| | | { |
| | | std::string str = getWindowName(hwnd); |
| | | if (str.find(name) != string::npos) |
| | | { |
| | | list.push_back(hwnd); |
| | | } |
| | | hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); |
| | | } |
| | | |
| | | return list; |
| | | } |
| | | |
| | | |
| | | string Win32Util::getWindowName(HWND hwnd) { |
| | | int length = GetWindowTextLength(hwnd); |
| | | TCHAR getbuf[10240]; |
| | | GetWindowText(hwnd, getbuf, length + 1); |
| | | int iLen = WideCharToMultiByte(CP_ACP, 0, getbuf, -1, NULL, 0, NULL, NULL); //首先计算TCHAR 长度。 |
| | | char* chRtn = (char*)alloca(iLen * sizeof(char)); //定义一个 TCHAR 长度大小的 CHAR 类型。 |
| | | WideCharToMultiByte(CP_ACP, 0, getbuf, -1, chRtn, iLen, NULL, NULL); //将TCHAR 类型的数据转换为 CHAR 类型。 |
| | | std::string str(chRtn); |
| | | return str; |
| | | } |
| | | |
| | | string Win32Util::getClassName(HWND hwnd) |
| | | { |
| | | |
| | | TCHAR className[1024]; |
| | | GetClassName(hwnd, className, 1024); |
| | | string st = convertLPWSTRToUTF8(className); |
| | | return st; |
| | | } |
| | | |
| | | wstring Win32Util::getText(HWND hwnd) |
| | | { |
| | | int length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); |
| | | if (length == -1) |
| | | return L""; |
| | | wchar_t* buffer = new wchar_t[length + 1]; |
| | | SendMessage(hwnd, WM_GETTEXT, length + 1, (LPARAM)buffer); |
| | | std::wstring str(buffer); |
| | | delete[] buffer; |
| | | return str; |
| | | } |
| | | |
| | | |
| | | void Win32Util::click(int delay) { |
| | | thread clickRunner(clickRunner, delay); |
| | | clickRunner.join(); |
| | | } |
| | | |
| | | void Win32Util::click(int x, int y, int delay) { |
| | | thread clickRunner(moveRunner, x, y, delay); |
| | | clickRunner.join(); |
| | | click(); |
| | | } |
| | | |
| | | void Win32Util::mouseMove(int x, int y, int delay) { |
| | | thread clickRunner(moveRunner, x, y, delay); |
| | | clickRunner.join(); |
| | | } |
| | | |
| | | void Win32Util::focus(HWND hwnd) { |
| | | SetForegroundWindow(hwnd); |
| | | SetFocus(hwnd); |
| | | } |
| | | |
| | | |
| | | |
| | | //键盘输入数字 |
| | | void Win32Util::keyboardNum(string num, int delay) { |
| | | thread runner(kbNumRunner, num, delay); |
| | | runner.join(); |
| | | } |
| | | |
| | | //键盘输入其他键 |
| | | void Win32Util::keyboard(int code, int delay) { |
| | | thread runner(kbKeyRunner, code, delay); |
| | | runner.join(); |
| | | } |
| | | |
| | | void Win32Util::virtualKeyboard(HWND hwnd, int code) |
| | | { |
| | | PostMessage(hwnd, WM_KEYDOWN, code, 0); |
| | | PostMessage(hwnd, WM_KEYUP, code, 0); |
| | | } |
| | | |
| | | void Win32Util::keyboardPaste() |
| | | { |
| | | keybd_event(VK_CONTROL, 0, 0, 0); // 按下CTRL键 |
| | | keybd_event('V', 0, 0, 0); // 按下a键 |
| | | Sleep(50); |
| | | keybd_event('V', 0, KEYEVENTF_KEYUP, 0);// 松开a键 |
| | | keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);// 松开CTRL键 |
| | | } |
| | | |
| | | DEVMODE Win32Util::getL2ScreenInfo() |
| | | { |
| | | //获取屏幕数量 |
| | | DEVMODE dm; |
| | | int screenNUm = GetSystemMetrics(SM_CMONITORS); |
| | | for (int i = 0; i < screenNUm; i++) { |
| | | DISPLAY_DEVICE device; |
| | | ZeroMemory(&device, sizeof(DISPLAY_DEVICE)); |
| | | device.cb = sizeof(DISPLAY_DEVICE); |
| | | EnumDisplayDevices(NULL, i, &device, NULL); |
| | | |
| | | |
| | | ZeroMemory(&dm, sizeof(dm)); |
| | | dm.dmSize = sizeof(dm); |
| | | EnumDisplaySettings(device.DeviceName, ENUM_CURRENT_SETTINGS, &dm); |
| | | |
| | | if (dm.dmPelsWidth > 3000) { |
| | | return dm; |
| | | } |
| | | } |
| | | throw string("尚未找到适合L2的显示设备"); |
| | | return DEVMODE(); |
| | | } |
| | | |
| | | void Win32Util::moveWin(HWND win, int x, int y, int width, int height) { |
| | | MoveWindow(win, x, y, width, height, TRUE); |
| | | } |
| | | |
| | | bool Win32Util::isWindowShow(HWND win) { |
| | | return IsWindowVisible(win); |
| | | } |
| | | |
| | | void Win32Util::showWindow(HWND hwnd) { |
| | | ShowWindow(hwnd, SW_SHOWNORMAL); |
| | | } |
| | | |
| | | |
| | | void Win32Util::rollMouseWheel(bool back, HWND win, int x, int y) |
| | | { |
| | | //back-是否往后滚 |
| | | PostMessage(win, WM_MOUSEWHEEL, back ? 0xFF880000 : 0x00780000, MAKEWORD(x, y)); |
| | | } |
| | | |
| | | void Win32Util::getWindowRect(HWND hwnd, RECT* rect) |
| | | { |
| | | GetWindowRect(hwnd, rect); |
| | | } |
| | | |
| | | void Win32Util::visualClick(HWND hwnd, LPARAM pos) |
| | | { |
| | | PostMessage(hwnd, WM_LBUTTONDOWN, 0x00000001, pos); |
| | | PostMessage(hwnd, WM_LBUTTONUP, 0x00000000, pos); |
| | | } |
| | | |
| | | string Win32Util::getNowTime() |
| | | { |
| | | // 获取系统时间 |
| | | SYSTEMTIME sys; |
| | | GetLocalTime(&sys); |
| | | int h = sys.wHour; |
| | | int m = sys.wMinute; |
| | | int s = sys.wSecond; |
| | | string st = ""; |
| | | if (h < 10) { |
| | | st.append("0"); |
| | | } |
| | | st.append(to_string(h)); |
| | | st.append(":"); |
| | | if (m < 10) { |
| | | st.append("0"); |
| | | } |
| | | st.append(to_string(m)); |
| | | st.append(":"); |
| | | if (s < 10) { |
| | | st.append("0"); |
| | | } |
| | | st.append(to_string(s)); |
| | | return st; |
| | | } |
| | | |
| | | void Win32Util::sendMessage(HWND hwnd, UINT msg, LPARAM p0, LPARAM p1) |
| | | { |
| | | SendMessage(hwnd, msg, p0, p1); |
| | | } |
| | | |
| | | void Win32Util::postMessage(HWND hwnd, UINT msg, LPARAM p0, LPARAM p1) |
| | | { |
| | | PostMessage(hwnd, msg, p0, p1); |
| | | } |
| | | |
| | | void Win32Util::input_num(HWND hwnd, string num_str) |
| | | { |
| | | for (int i = 0; i < num_str.size(); i++) |
| | | { |
| | | SendMessage(hwnd, WM_KEYDOWN, num_str.c_str()[i], 0); |
| | | PostMessage(hwnd, WM_KEYUP, num_str.c_str()[i], 0); |
| | | Sleep(10); |
| | | } |
| | | } |
| | | |
| | | void Win32Util::addToTHS(string code) |
| | | { |
| | | |
| | | string leftCode = code.substr(1, 5); |
| | | |
| | | list<HWND> hwnds = searchWindow("看盘页面"); |
| | | HWND origin_hwnd = 0; |
| | | |
| | | |
| | | for (list<HWND>::iterator e = hwnds.begin(); e != hwnds.end(); ++e) { |
| | | HWND hwnd = *e; |
| | | string name = Win32Util::getWindowName(hwnd); |
| | | if (name.find("同花顺") >= 0) { |
| | | origin_hwnd = hwnd; |
| | | } |
| | | } |
| | | if (origin_hwnd <= 0) { |
| | | throw string("没有找到看盘页面"); |
| | | return; |
| | | } |
| | | input_num(origin_hwnd, code.substr(0, 1)); |
| | | |
| | | Sleep(100); |
| | | hwnds.clear(); |
| | | HWND topHwnd = GetDesktopWindow(); |
| | | |
| | | |
| | | |
| | | |
| | | HWND temp = 0; |
| | | while (TRUE) { |
| | | if (temp > 0 && isWindowShow(temp)) { |
| | | string className = getClassName(temp); |
| | | if (className.find("Afx:") == 0) { |
| | | if (className.substr(className.length() - 2, 2).find( ":0")==0) { |
| | | hwnds.push_back(temp); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | temp = FindWindowEx(topHwnd, temp, NULL, NULL); |
| | | if (temp <= 0) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | if (hwnds.size() > 0) |
| | | { |
| | | HWND hwndroot = *(hwnds.begin()); |
| | | HWND hwnd = FindWindowEx(hwndroot, NULL, L"Edit", L""); |
| | | input_num(hwnd, leftCode); |
| | | Sleep(400); |
| | | focus(hwndroot); |
| | | SendMessage(hwndroot, WM_KEYDOWN, VK_RETURN, 0); |
| | | Sleep(10); |
| | | PostMessage(hwndroot, WM_KEYUP, VK_RETURN, 0); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
New file |
| | |
| | | #pragma once |
| | | #include <list> |
| | | #include <string> |
| | | #include <wtypes.h> |
| | | using namespace std; |
| | | class Win32Util |
| | | { |
| | | private: |
| | | static std::string convertLPWSTRToUTF8(LPWSTR lpwstr); |
| | | |
| | | public: |
| | | |
| | | |
| | | //按照名称搜索窗体 |
| | | static list<HWND> searchWindow(string name); |
| | | |
| | | //获取窗口名称 |
| | | static string getWindowName(HWND hwnd); |
| | | |
| | | |
| | | static string getClassName(HWND hwnd); |
| | | |
| | | //获取获取控件内容 |
| | | static wstring getText(HWND hwnd); |
| | | |
| | | //单击 |
| | | static void click(int delay = 0); |
| | | |
| | | //单击指定位置 |
| | | static void click(int x, int y, int delay = 0); |
| | | |
| | | //移动鼠标 |
| | | static void mouseMove(int x, int y, int delay = 0); |
| | | |
| | | //获取焦点 |
| | | static void focus(HWND hwnd); |
| | | |
| | | //键盘输入数字 |
| | | static void keyboardNum(string num, int delay = 0); |
| | | |
| | | //键盘输入其他键 |
| | | static void keyboard(int code, int delay = 0); |
| | | |
| | | //虚拟键入 |
| | | static void virtualKeyboard(HWND hwnd, int code); |
| | | |
| | | //键盘键入粘贴 |
| | | static void keyboardPaste(); |
| | | |
| | | //获取L2屏幕数据 |
| | | static DEVMODE getL2ScreenInfo(); |
| | | |
| | | //移动窗口 |
| | | static void moveWin(HWND win, int x, int y, int width, int height); |
| | | |
| | | //窗体是否显示 |
| | | static bool isWindowShow(HWND hwnd); |
| | | //显示窗口 |
| | | static void showWindow(HWND hwnd); |
| | | |
| | | //鼠标滚动 |
| | | static void rollMouseWheel(bool back, HWND win, int x, int y); |
| | | |
| | | //获取位置 |
| | | static void getWindowRect(HWND hwnd, RECT* rect); |
| | | |
| | | //虚拟点击 |
| | | static void visualClick(HWND hwnd, LPARAM pos); |
| | | |
| | | //获取现在的时间 |
| | | static string getNowTime(); |
| | | |
| | | static void sendMessage(HWND hwnd, UINT msg, LPARAM p0, LPARAM p1); |
| | | |
| | | static void postMessage(HWND hwnd, UINT msg, LPARAM p0, LPARAM p1); |
| | | |
| | | static void input_num(HWND hwnd, string content); |
| | | |
| | | static void addToTHS(string code); |
| | | }; |
| | | |
New file |
| | |
| | | #include "md5.h" |
| | | /* Define the static member of MD5. */ |
| | | const byte MD5::PADDING[64] = { 0x80 }; |
| | | const char MD5::HEX_NUMBERS[16] = { |
| | | '0', '1', '2', '3', |
| | | '4', '5', '6', '7', |
| | | '8', '9', 'a', 'b', |
| | | 'c', 'd', 'e', 'f' |
| | | }; |
| | | |
| | | MD5::MD5(const string& message) { |
| | | finished = false; |
| | | /* Reset number of bits. */ |
| | | count[0] = count[1] = 0; |
| | | /* Initialization constants. */ |
| | | state[0] = 0x67452301; |
| | | state[1] = 0xefcdab89; |
| | | state[2] = 0x98badcfe; |
| | | state[3] = 0x10325476; |
| | | |
| | | /* Initialization the object according to message. */ |
| | | init((const byte*)message.c_str(), message.length()); |
| | | } |
| | | |
| | | /** |
| | | * @Generate md5 digest. |
| | | * |
| | | * @return the message-digest. |
| | | * |
| | | */ |
| | | const byte* MD5::getDigest() { |
| | | if (!finished) { |
| | | finished = true; |
| | | |
| | | byte bits[8]; |
| | | bit32 oldState[4]; |
| | | bit32 oldCount[2]; |
| | | bit32 index, padLen; |
| | | |
| | | /* Save current state and count. */ |
| | | memcpy(oldState, state, 16); |
| | | memcpy(oldCount, count, 8); |
| | | |
| | | /* Save number of bits */ |
| | | encode(count, bits, 8); |
| | | |
| | | /* Pad out to 56 mod 64. */ |
| | | index = (bit32)((count[0] >> 3) & 0x3f); |
| | | padLen = (index < 56) ? (56 - index) : (120 - index); |
| | | init(PADDING, padLen); |
| | | |
| | | /* Append length (before padding) */ |
| | | init(bits, 8); |
| | | |
| | | /* Store state in digest */ |
| | | encode(state, digest, 16); |
| | | |
| | | /* Restore current state and count. */ |
| | | memcpy(state, oldState, 16); |
| | | memcpy(count, oldCount, 8); |
| | | } |
| | | return digest; |
| | | } |
| | | |
| | | /** |
| | | * @Initialization the md5 object, processing another message block, |
| | | * and updating the context. |
| | | * |
| | | * @param {input} the input message. |
| | | * |
| | | * @param {len} the number btye of message. |
| | | * |
| | | */ |
| | | void MD5::init(const byte* input, size_t len) { |
| | | |
| | | bit32 i, index, partLen; |
| | | |
| | | finished = false; |
| | | |
| | | /* Compute number of bytes mod 64 */ |
| | | index = (bit32)((count[0] >> 3) & 0x3f); |
| | | |
| | | /* update number of bits */ |
| | | if ((count[0] += ((bit32)len << 3)) < ((bit32)len << 3)) { |
| | | ++count[1]; |
| | | } |
| | | count[1] += ((bit32)len >> 29); |
| | | |
| | | partLen = 64 - index; |
| | | |
| | | /* transform as many times as possible. */ |
| | | if (len >= partLen) { |
| | | |
| | | memcpy(&buffer[index], input, partLen); |
| | | transform(buffer); |
| | | |
| | | for (i = partLen; i + 63 < len; i += 64) { |
| | | transform(&input[i]); |
| | | } |
| | | index = 0; |
| | | |
| | | } |
| | | else { |
| | | i = 0; |
| | | } |
| | | |
| | | /* Buffer remaining input */ |
| | | memcpy(&buffer[index], &input[i], len - i); |
| | | } |
| | | |
| | | |
| | | void MD5::transform(const byte block[64]) { |
| | | |
| | | bit32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; |
| | | |
| | | decode(block, x, 64); |
| | | |
| | | /* Round 1 */ |
| | | FF(a, b, c, d, x[0], s11, 0xd76aa478); |
| | | FF(d, a, b, c, x[1], s12, 0xe8c7b756); |
| | | FF(c, d, a, b, x[2], s13, 0x242070db); |
| | | FF(b, c, d, a, x[3], s14, 0xc1bdceee); |
| | | FF(a, b, c, d, x[4], s11, 0xf57c0faf); |
| | | FF(d, a, b, c, x[5], s12, 0x4787c62a); |
| | | FF(c, d, a, b, x[6], s13, 0xa8304613); |
| | | FF(b, c, d, a, x[7], s14, 0xfd469501); |
| | | FF(a, b, c, d, x[8], s11, 0x698098d8); |
| | | FF(d, a, b, c, x[9], s12, 0x8b44f7af); |
| | | FF(c, d, a, b, x[10], s13, 0xffff5bb1); |
| | | FF(b, c, d, a, x[11], s14, 0x895cd7be); |
| | | FF(a, b, c, d, x[12], s11, 0x6b901122); |
| | | FF(d, a, b, c, x[13], s12, 0xfd987193); |
| | | FF(c, d, a, b, x[14], s13, 0xa679438e); |
| | | FF(b, c, d, a, x[15], s14, 0x49b40821); |
| | | |
| | | /* Round 2 */ |
| | | GG(a, b, c, d, x[1], s21, 0xf61e2562); |
| | | GG(d, a, b, c, x[6], s22, 0xc040b340); |
| | | GG(c, d, a, b, x[11], s23, 0x265e5a51); |
| | | GG(b, c, d, a, x[0], s24, 0xe9b6c7aa); |
| | | GG(a, b, c, d, x[5], s21, 0xd62f105d); |
| | | GG(d, a, b, c, x[10], s22, 0x2441453); |
| | | GG(c, d, a, b, x[15], s23, 0xd8a1e681); |
| | | GG(b, c, d, a, x[4], s24, 0xe7d3fbc8); |
| | | GG(a, b, c, d, x[9], s21, 0x21e1cde6); |
| | | GG(d, a, b, c, x[14], s22, 0xc33707d6); |
| | | GG(c, d, a, b, x[3], s23, 0xf4d50d87); |
| | | GG(b, c, d, a, x[8], s24, 0x455a14ed); |
| | | GG(a, b, c, d, x[13], s21, 0xa9e3e905); |
| | | GG(d, a, b, c, x[2], s22, 0xfcefa3f8); |
| | | GG(c, d, a, b, x[7], s23, 0x676f02d9); |
| | | GG(b, c, d, a, x[12], s24, 0x8d2a4c8a); |
| | | |
| | | /* Round 3 */ |
| | | HH(a, b, c, d, x[5], s31, 0xfffa3942); |
| | | HH(d, a, b, c, x[8], s32, 0x8771f681); |
| | | HH(c, d, a, b, x[11], s33, 0x6d9d6122); |
| | | HH(b, c, d, a, x[14], s34, 0xfde5380c); |
| | | HH(a, b, c, d, x[1], s31, 0xa4beea44); |
| | | HH(d, a, b, c, x[4], s32, 0x4bdecfa9); |
| | | HH(c, d, a, b, x[7], s33, 0xf6bb4b60); |
| | | HH(b, c, d, a, x[10], s34, 0xbebfbc70); |
| | | HH(a, b, c, d, x[13], s31, 0x289b7ec6); |
| | | HH(d, a, b, c, x[0], s32, 0xeaa127fa); |
| | | HH(c, d, a, b, x[3], s33, 0xd4ef3085); |
| | | HH(b, c, d, a, x[6], s34, 0x4881d05); |
| | | HH(a, b, c, d, x[9], s31, 0xd9d4d039); |
| | | HH(d, a, b, c, x[12], s32, 0xe6db99e5); |
| | | HH(c, d, a, b, x[15], s33, 0x1fa27cf8); |
| | | HH(b, c, d, a, x[2], s34, 0xc4ac5665); |
| | | |
| | | /* Round 4 */ |
| | | II(a, b, c, d, x[0], s41, 0xf4292244); |
| | | II(d, a, b, c, x[7], s42, 0x432aff97); |
| | | II(c, d, a, b, x[14], s43, 0xab9423a7); |
| | | II(b, c, d, a, x[5], s44, 0xfc93a039); |
| | | II(a, b, c, d, x[12], s41, 0x655b59c3); |
| | | II(d, a, b, c, x[3], s42, 0x8f0ccc92); |
| | | II(c, d, a, b, x[10], s43, 0xffeff47d); |
| | | II(b, c, d, a, x[1], s44, 0x85845dd1); |
| | | II(a, b, c, d, x[8], s41, 0x6fa87e4f); |
| | | II(d, a, b, c, x[15], s42, 0xfe2ce6e0); |
| | | II(c, d, a, b, x[6], s43, 0xa3014314); |
| | | II(b, c, d, a, x[13], s44, 0x4e0811a1); |
| | | II(a, b, c, d, x[4], s41, 0xf7537e82); |
| | | II(d, a, b, c, x[11], s42, 0xbd3af235); |
| | | II(c, d, a, b, x[2], s43, 0x2ad7d2bb); |
| | | II(b, c, d, a, x[9], s44, 0xeb86d391); |
| | | |
| | | state[0] += a; |
| | | state[1] += b; |
| | | state[2] += c; |
| | | state[3] += d; |
| | | } |
| | | |
| | | /** |
| | | * @Encodes input (unsigned long) into output (byte). |
| | | * |
| | | * @param {input} usigned long. |
| | | * |
| | | * @param {output} byte. |
| | | * |
| | | * @param {length} the length of input. |
| | | * |
| | | */ |
| | | void MD5::encode(const bit32* input, byte* output, size_t length) { |
| | | |
| | | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { |
| | | output[j] = (byte)(input[i] & 0xff); |
| | | output[j + 1] = (byte)((input[i] >> 8) & 0xff); |
| | | output[j + 2] = (byte)((input[i] >> 16) & 0xff); |
| | | output[j + 3] = (byte)((input[i] >> 24) & 0xff); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @Decodes input (byte) into output (usigned long). |
| | | * |
| | | * @param {input} bytes. |
| | | * |
| | | * @param {output} unsigned long. |
| | | * |
| | | * @param {length} the length of input. |
| | | * |
| | | */ |
| | | void MD5::decode(const byte* input, bit32* output, size_t length) { |
| | | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { |
| | | output[i] = ((bit32)input[j]) | (((bit32)input[j + 1]) << 8) | |
| | | (((bit32)input[j + 2]) << 16) | (((bit32)input[j + 3]) << 24); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @Convert digest to string value. |
| | | * |
| | | * @return the hex string of digest. |
| | | * |
| | | */ |
| | | string MD5::toStr() { |
| | | const byte* digest_ = getDigest(); |
| | | string str; |
| | | str.reserve(16 << 1); |
| | | for (size_t i = 0; i < 16; ++i) { |
| | | int t = digest_[i]; |
| | | int a = t / 16; |
| | | int b = t % 16; |
| | | str.append(1, HEX_NUMBERS[a]); |
| | | str.append(1, HEX_NUMBERS[b]); |
| | | } |
| | | return str; |
| | | } |
| | | |
New file |
| | |
| | | #pragma once |
| | | // |
| | | // Created by Admin on 2022/9/24. |
| | | // |
| | | |
| | | #ifndef CODEMD5_MD5_H |
| | | #define CODEMD5_MD5_H |
| | | |
| | | /* Parameters of MD5. */ |
| | | #define s11 7 |
| | | #define s12 12 |
| | | #define s13 17 |
| | | #define s14 22 |
| | | |
| | | #define s21 5 |
| | | #define s22 9 |
| | | #define s23 14 |
| | | #define s24 20 |
| | | |
| | | #define s31 4 |
| | | #define s32 11 |
| | | #define s33 16 |
| | | #define s34 23 |
| | | |
| | | #define s41 6 |
| | | #define s42 10 |
| | | #define s43 15 |
| | | #define s44 21 |
| | | |
| | | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) |
| | | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) |
| | | #define H(x, y, z) ((x) ^ (y) ^ (z)) |
| | | #define I(x, y, z) ((y) ^ ((x) | (~z))) |
| | | |
| | | #define ROTATELEFT(num, n) (((num) << (n)) | ((num) >> (32-(n)))) |
| | | |
| | | #define FF(a, b, c, d, x, s, ac) { \ |
| | | (a) += F ((b), (c), (d)) + (x) + ac; \ |
| | | (a) = ROTATELEFT ((a), (s)); \ |
| | | (a) += (b); \ |
| | | } |
| | | #define GG(a, b, c, d, x, s, ac) { \ |
| | | (a) += G ((b), (c), (d)) + (x) + ac; \ |
| | | (a) = ROTATELEFT ((a), (s)); \ |
| | | (a) += (b); \ |
| | | } |
| | | #define HH(a, b, c, d, x, s, ac) { \ |
| | | (a) += H ((b), (c), (d)) + (x) + ac; \ |
| | | (a) = ROTATELEFT ((a), (s)); \ |
| | | (a) += (b); \ |
| | | } |
| | | #define II(a, b, c, d, x, s, ac) { \ |
| | | (a) += I ((b), (c), (d)) + (x) + ac; \ |
| | | (a) = ROTATELEFT ((a), (s)); \ |
| | | (a) += (b); \ |
| | | } |
| | | |
| | | #include <string> |
| | | #include <cstring> |
| | | |
| | | using std::string; |
| | | |
| | | /* Define of btye.*/ |
| | | typedef unsigned char byte; |
| | | /* Define of byte. */ |
| | | typedef unsigned int bit32; |
| | | |
| | | class MD5 { |
| | | public: |
| | | /* Construct a MD5 object with a string. */ |
| | | MD5(const string& message); |
| | | |
| | | /* Generate md5 digest. */ |
| | | const byte* getDigest(); |
| | | |
| | | /* Convert digest to string value */ |
| | | string toStr(); |
| | | |
| | | private: |
| | | /* Initialization the md5 object, processing another message block, |
| | | * and updating the context.*/ |
| | | void init(const byte* input, size_t len); |
| | | |
| | | /* MD5 basic transformation. Transforms state based on block. */ |
| | | void transform(const byte block[64]); |
| | | |
| | | /* Encodes input (usigned long) into output (byte). */ |
| | | void encode(const bit32* input, byte* output, size_t length); |
| | | |
| | | /* Decodes input (byte) into output (usigned long). */ |
| | | void decode(const byte* input, bit32* output, size_t length); |
| | | |
| | | private: |
| | | /* Flag for mark whether calculate finished. */ |
| | | bool finished; |
| | | |
| | | /* state (ABCD). */ |
| | | bit32 state[4]; |
| | | |
| | | /* number of bits, low-order word first. */ |
| | | bit32 count[2]; |
| | | |
| | | /* input buffer. */ |
| | | byte buffer[64]; |
| | | |
| | | /* message digest. */ |
| | | byte digest[16]; |
| | | |
| | | /* padding for calculate. */ |
| | | static const byte PADDING[64]; |
| | | |
| | | /* Hex numbers. */ |
| | | static const char HEX_NUMBERS[16]; |
| | | }; |
| | | #endif //CODEMD5_MD5_H |
| | | |
| | | |
| | | |