448 lines
12 KiB
C++
448 lines
12 KiB
C++
#include "StdAfx.h"
|
|
#include "CmdQuery.h"
|
|
#include "CoreTools.h"
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include<algorithm>
|
|
#include "initools.h"
|
|
|
|
namespace
|
|
{
|
|
using namespace CmdQuery;
|
|
|
|
MnuFiles g_mnuFiles;
|
|
std::map<WPARAM, CString> g_VKTable;
|
|
std::set<WPARAM> 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<WPARAM>::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<CString, CString> datas;
|
|
IniTools::getSectionContent(FilePath::GetSysDir() + _T("\\product.ini")
|
|
, _T("MENUS")
|
|
, datas);
|
|
if (datas.empty()) return 0;
|
|
|
|
CString sFile(_T("")), sTitle(_T(""));
|
|
std::map<CString, CString>::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<WPARAM, CString>::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<WPARAM, CString>::const_iterator it = g_VKTable.find(key);
|
|
if (it == g_VKTable.end()) return _T("");
|
|
return it->second;
|
|
}
|
|
|
|
bool checkHotkey(const std::map<WPARAM, CString>& keys)
|
|
{
|
|
if (keys.empty()) return true;
|
|
// 先检查有没有一般字符
|
|
bool bHasNormalKey(false);
|
|
std::map<WPARAM, CString>::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<WPARAM> hotkeys;
|
|
getHotKey(hotkeys);
|
|
if (hotkeys.empty()) return _T("");
|
|
|
|
std::wstringstream ws;
|
|
std::set<WPARAM>::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<WPARAM>& 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<CString> 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<WPARAM, LPCTSTR>((LPCTSTR)vec[i]));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void saveHotKey(std::map<WPARAM, CString>& chs)
|
|
{
|
|
std::ofstream fs(FilePath::getProgramDataFolder() + FILE_HOTKEYS);
|
|
if (fs.is_open())
|
|
{
|
|
g_hotkeys.clear();
|
|
std::map<WPARAM, CString>::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);
|
|
}
|
|
} |