#include "StdAfx.h" #include "CmdQuery.h" #include "CoreTools.h" #include #include #include #include "initools.h" namespace { using namespace CmdQuery; MnuFiles g_mnuFiles; std::map g_VKTable; std::set g_hotkeys; #if ARX > 22 static bool InputKeyWord(MSG* msg) #else static BOOL InputKeyWord(MSG* msg) #endif { BOOL bRet = FALSE; if (!acdbCurDwg()) { return bRet; } // 没有关键字输入的时候支持判断结果 switch (msg->message) { case WM_KEYDOWN: // 键盘输入关键字 { std::set::const_iterator it = g_hotkeys.begin(); for (; it != g_hotkeys.end(); ++it) { if (!(GetKeyState(*it) & 0x8000)) return FALSE; } acedPostCommand(_T("cmds ")); return TRUE; } break; default: break; } return FALSE; } bool isNormalKey(WPARAM key) { if (key != VK_ESCAPE && key != VK_TAB && key != VK_CAPITAL && key != VK_SHIFT && key != VK_CONTROL && key != VK_LWIN && key != VK_RWIN && key != VK_MENU && key != VK_RETURN && key != VK_BACK ) return true; return false; } int initVKTable() { g_VKTable.clear(); g_VKTable.insert(std::make_pair(VK_F1, _T("F1"))); g_VKTable.insert(std::make_pair(VK_F2, _T("F2"))); g_VKTable.insert(std::make_pair(VK_F3, _T("F3"))); g_VKTable.insert(std::make_pair(VK_F4, _T("F4"))); g_VKTable.insert(std::make_pair(VK_F5, _T("F5"))); g_VKTable.insert(std::make_pair(VK_F6, _T("F6"))); g_VKTable.insert(std::make_pair(VK_F7, _T("F7"))); g_VKTable.insert(std::make_pair(VK_F8, _T("F8"))); g_VKTable.insert(std::make_pair(VK_F9, _T("F9"))); g_VKTable.insert(std::make_pair(VK_F10, _T("F10"))); g_VKTable.insert(std::make_pair(VK_F11, _T("F11"))); g_VKTable.insert(std::make_pair(VK_F12, _T("F12"))); g_VKTable.insert(std::make_pair(VK_NUMPAD0, _T("Num0"))); g_VKTable.insert(std::make_pair(VK_NUMPAD1, _T("Num1"))); g_VKTable.insert(std::make_pair(VK_NUMPAD2, _T("Num2"))); g_VKTable.insert(std::make_pair(VK_NUMPAD3, _T("Num3"))); g_VKTable.insert(std::make_pair(VK_NUMPAD4, _T("Num4"))); g_VKTable.insert(std::make_pair(VK_NUMPAD5, _T("Num5"))); g_VKTable.insert(std::make_pair(VK_NUMPAD6, _T("Num6"))); g_VKTable.insert(std::make_pair(VK_NUMPAD7, _T("Num7"))); g_VKTable.insert(std::make_pair(VK_NUMPAD8, _T("Num8"))); g_VKTable.insert(std::make_pair(VK_NUMPAD9, _T("Num9"))); g_VKTable.insert(std::make_pair(VK_MULTIPLY, _T("*"))); g_VKTable.insert(std::make_pair(VK_ADD, _T("+"))); g_VKTable.insert(std::make_pair(VK_SEPARATOR, _T("SEP"))); g_VKTable.insert(std::make_pair(VK_SUBTRACT, _T("-"))); g_VKTable.insert(std::make_pair(VK_DECIMAL, _T("."))); g_VKTable.insert(std::make_pair(VK_DIVIDE, _T("/"))); g_VKTable.insert(std::make_pair(VK_NUMLOCK, _T("NumLock"))); g_VKTable.insert(std::make_pair(VK_SCROLL, _T("SCR"))); g_VKTable.insert(std::make_pair(VK_PAUSE, _T("PAU"))); g_VKTable.insert(std::make_pair(VK_ESCAPE, _T("ESC"))); g_VKTable.insert(std::make_pair(VK_RETURN, _T("RET"))); g_VKTable.insert(std::make_pair(VK_TAB, _T("TAB"))); g_VKTable.insert(std::make_pair(VK_CAPITAL, _T("CAP"))); g_VKTable.insert(std::make_pair(VK_SHIFT, _T("SHIFT"))); g_VKTable.insert(std::make_pair(VK_CONTROL, _T("CTRL"))); g_VKTable.insert(std::make_pair(VK_MENU, _T("ALT"))); g_VKTable.insert(std::make_pair(VK_SPACE, _T("SPA"))); g_VKTable.insert(std::make_pair(VK_BACK, _T("BACK"))); g_VKTable.insert(std::make_pair(VK_LWIN, _T("LWIN"))); g_VKTable.insert(std::make_pair(VK_RWIN, _T("RWIN"))); g_VKTable.insert(std::make_pair(VK_INSERT, _T("INS"))); g_VKTable.insert(std::make_pair(VK_HOME, _T("HOME"))); g_VKTable.insert(std::make_pair(VK_PRIOR, _T("PAUP"))); g_VKTable.insert(std::make_pair(VK_NEXT, _T("PADN"))); g_VKTable.insert(std::make_pair(VK_END, _T("END"))); g_VKTable.insert(std::make_pair(VK_DELETE, _T("DEL"))); g_VKTable.insert(std::make_pair(VK_LEFT, _T("LEFT"))); g_VKTable.insert(std::make_pair(VK_UP, _T("UP"))); g_VKTable.insert(std::make_pair(VK_DOWN, _T("DN"))); g_VKTable.insert(std::make_pair(VK_RIGHT, _T("RIGHT"))); g_VKTable.insert(std::make_pair(VK_OEM_1, _T(";:"))); g_VKTable.insert(std::make_pair(VK_OEM_7, _T("\'\""))); g_VKTable.insert(std::make_pair(VK_OEM_COMMA, _T(",<"))); g_VKTable.insert(std::make_pair(VK_OEM_PERIOD, _T(".>"))); g_VKTable.insert(std::make_pair(VK_OEM_2, _T("/?"))); g_VKTable.insert(std::make_pair(VK_OEM_3, _T("`~"))); g_VKTable.insert(std::make_pair(VK_OEM_PLUS, _T("=+"))); g_VKTable.insert(std::make_pair(VK_OEM_MINUS, _T("-_"))); g_VKTable.insert(std::make_pair(VK_OEM_4, _T("[{"))); g_VKTable.insert(std::make_pair(VK_OEM_5, _T("\\|"))); g_VKTable.insert(std::make_pair(VK_OEM_6, _T("]}"))); for (WPARAM wp = 0x30; wp <= 0x39; ++wp) g_VKTable.insert(std::make_pair(wp, CString(wchar_t(wp)))); for (WPARAM wp = 0x41; wp <= 0x5A; ++wp) g_VKTable.insert(std::make_pair(wp, CString(wchar_t(wp)))); return 0; } std::string replace(const std::string& str , const std::string& src , const std::string& dest) { std::string ret; std::string::size_type pos_begin = 0; std::string::size_type pos = str.find(src); while (pos != std::string::npos) { ret.append(str.data() + pos_begin, pos - pos_begin); ret += dest; pos_begin = pos + 1; pos = str.find(src, pos_begin); } if (pos_begin < str.length()) { ret.append(str.begin() + pos_begin, str.end()); } return ret; } // 0-begin 1-normal 2-end int analyzeCmdLine(const std::string &s, std::string &cmd, std::string &title) { std::string sFirst = s.substr(0, 2); if (sFirst == "//") return -1; sFirst = s.substr(0, 3); if (sFirst == "***") return -1; sFirst = s.substr(0, 9); if (sFirst == "ID_SCREEN") return -1; if (s.find("[--]") != -1) return -1; int iBeginMask = s.find("[->"); int iEndMask = s.find("[<-"); int iTitleBegin = s.find('['); int iTitleLast = s.find(']'); if (iBeginMask != -1) { title = s.substr(iBeginMask + 3, iTitleLast - (iBeginMask + 2) - 1); return 0; } if (iEndMask != -1) { title = s.substr(iEndMask + 3, iTitleLast - (iEndMask + 2) - 1); if (iTitleLast + 1 < s.size()) cmd = s.substr(iTitleLast + 1); return 2; } if (iTitleBegin != -1) { title = s.substr(iTitleBegin + 1, iTitleLast - (iTitleBegin + 0) - 1); if (iTitleLast + 1 < s.size()) cmd = s.substr(iTitleLast + 1); return 1; } return -1; } bool makeMnuFile(MnuFile &mf) { mf.m_CmdGroups.clear(); std::ifstream fs(mf.m_sFile); if (!fs.is_open()) return false; int nRel(-1); std::string s, cmd, title; CmdGroup cmdgrp; CmdItem ci; while (!fs.eof()) { s.clear(); std::getline(fs, s); nRel = analyzeCmdLine(s, cmd, title); if (nRel == 0) { cmdgrp.m_CmdItems.clear(); title = replace(title, " ", ""); title = replace(title, "\t", ""); cmdgrp.m_sGroupName = title.c_str(); } else if (nRel == 1) { ci.m_sCmd = cmd.c_str(); title = replace(title, " ", ""); title = replace(title, "\t", ""); ci.m_sName = title.c_str(); ChiToLetter ch2Le; ch2Le.m_blnSimaple = TRUE; ci.m_sFirstLetter = ch2Le.GetLetter(ci.m_sName); ch2Le.m_blnSimaple = FALSE; ch2Le.m_blnAllBiG = FALSE; ci.m_sFullLetter = ch2Le.GetLetter(ci.m_sName); cmdgrp.m_CmdItems.push_back(ci); } else if (nRel == 2) { ci.m_sCmd = cmd.c_str(); title = replace(title, " ", ""); title = replace(title, "\t", ""); ci.m_sName = title.c_str(); ChiToLetter ch2Le; ch2Le.m_blnSimaple = TRUE; ci.m_sFirstLetter = ch2Le.GetLetter(ci.m_sName); ch2Le.m_blnSimaple = FALSE; ch2Le.m_blnAllBiG = FALSE; ci.m_sFullLetter = ch2Le.GetLetter(ci.m_sName); cmdgrp.m_CmdItems.push_back(ci); mf.m_CmdGroups.push_back(cmdgrp); } } fs.close(); return !mf.m_CmdGroups.empty(); } int initCmdGroups() { g_mnuFiles.clear(); std::map datas; IniTools::getSectionContent(FilePath::GetSysDir() + _T("\\product.ini") , _T("MENUS") , datas); if (datas.empty()) return 0; CString sFile(_T("")), sTitle(_T("")); std::map::const_iterator it = datas.begin(); MnuFile mf; for (; it != datas.end(); ++it) { mf.m_sFile = FilePath::GetSysDir() + _T("\\") + it->first + _T(".mnu"); mf.m_sTitle = it->second; if (makeMnuFile(mf)) g_mnuFiles.push_back(mf); } startHook(); initVKTable(); getHotKey(g_hotkeys); return 0; } static int g_init = initCmdGroups(); } namespace CmdQuery { #define FILE_HOTKEYS _T("\\cmds_hotkey.conf") void findCommand(LPCTSTR pszCmd, CmdQueryItems & items) { items.clear(); if (!pszCmd) return; if (g_mnuFiles.empty()) return; CString sCmd(pszCmd); sCmd = sCmd.MakeLower(); CmdQueryItem qi; for (size_t mnu = 0; mnu < g_mnuFiles.size(); ++mnu) { MnuFile &mf = g_mnuFiles[mnu]; for (size_t grp = 0; grp < mf.m_CmdGroups.size(); ++grp) { CmdGroup &cg = mf.m_CmdGroups[grp]; for (size_t ci = 0; ci < cg.m_CmdItems.size(); ++ci) { CmdItem &item = cg.m_CmdItems[ci]; if (item.m_sCmd.MakeLower().Find(sCmd) != -1 || item.m_sFirstLetter.MakeLower().Find(sCmd) != -1 || item.m_sFullLetter.MakeLower().Find(sCmd) != -1 || item.m_sName.Find(sCmd) != -1 ) { qi.m_cmdItem = item; qi.m_sGroupName = cg.m_sGroupName; qi.m_sFile = mf.m_sFile; qi.m_sMnuTitle = mf.m_sTitle; items.push_back(qi); } } } } } WPARAM getKeyByChar(LPCTSTR psz) { if (!psz) return NULL; std::map::const_iterator it = g_VKTable.begin(); for (; it != g_VKTable.end(); ++it) { if (it->second.Compare(psz) == 0) return it->first; } return NULL; } CString getCharByKey(WPARAM key) { std::map::const_iterator it = g_VKTable.find(key); if (it == g_VKTable.end()) return _T(""); return it->second; } bool checkHotkey(const std::map& keys) { if (keys.empty()) return true; // 先检查有没有一般字符 bool bHasNormalKey(false); std::map::const_iterator it = keys.begin(); for (; it != keys.end(); ++it) { if (isNormalKey(it->first)) { bHasNormalKey = true; break; } } bool bHasCtrlKey(false); // 再检查有没有(Ctrl、Alt、Shift)至少一种 for (it = keys.begin(); it != keys.end(); ++it) { if (it->first == VK_CONTROL || it->first == VK_MENU || it->first == VK_SHIFT) { bHasCtrlKey = true; break; } } return bHasNormalKey && bHasCtrlKey; } CString getHotkeyString() { std::set hotkeys; getHotKey(hotkeys); if (hotkeys.empty()) return _T(""); std::wstringstream ws; std::set::const_iterator it = hotkeys.begin(); for (; it != hotkeys.end(); ++it) ws << (LPCTSTR)getCharByKey(*it) << _T(" + "); return CString(_T("(当前热键:")) + ws.str().substr(0, ws.str().size() - 3).c_str() + _T(")") ; } void getHotKey(std::set& hotkeys) { hotkeys.clear(); hotkeys.insert(VK_CONTROL); hotkeys.insert(VK_MENU); hotkeys.insert('C'); CString path(FilePath::getProgramDataFolder() + FILE_HOTKEYS); if (_taccess(path, 0x0) != 0x0) return; std::ifstream fs((LPCTSTR)path); std::string s; std::vector vec; while (!fs.eof()) { vec.clear(); s.clear(); std::getline(fs, s); CoreTools::SplitString(CString(s.c_str()), _T(' '), vec); if (vec.size() < 2) return; hotkeys.clear(); for (size_t i = 0; i < vec.size(); ++i) { hotkeys.insert(TypeConvert::convert((LPCTSTR)vec[i])); } break; } } void saveHotKey(std::map& chs) { std::ofstream fs(FilePath::getProgramDataFolder() + FILE_HOTKEYS); if (fs.is_open()) { g_hotkeys.clear(); std::map::const_iterator it = chs.begin(); for (; it != chs.end(); ++it) { fs << it->first << " "; g_hotkeys.insert(it->first); } fs.close(); } } void startHook() { acedRegisterFilterWinMsg(InputKeyWord); } void endHook() { acedRemoveFilterWinMsg(InputKeyWord); } }