Windows下C++通用热键注册取消模块源代码实现
#include <iostream>
#include <functional>
// 终止递归函数
__inline static std::ostream& output_stream(std::ostream& os) { return os; }
// 使用可变参数模板实现参数打印到输出流(ostream) (递归调用)
template<typename T, typename ...Args>
__inline static std::ostream& output_stream(std::ostream& os, T t, Args...args) { os << t; output_stream(os, args...); return os; }
template<typename T, typename ...Args>
__inline static std::ostream& LogOut(T t, Args...args) { return output_stream(std::cout, t, args...); }
template<typename T, typename ...Args>
__inline static std::ostream& LogErr(T t, Args...args) { return output_stream(std::cerr, t, args...); }
class HotKeyWnd {
public:
void DoTask(){};
public:
class CHotKeyArg {
public:
UINT fsModifiers;
UINT vk;
std::string desc;
std::function<int(void*)> cb;
};
std::unordered_map<HWND, std::unordered_map<INT, CHotKeyArg>> m_mmHotKey = {
{NULL, {
{1,{MOD_ALT | MOD_NOREPEAT, 0x45, "ALT+E", [](void* p) {((HotKeyWnd*)p)->DoTask(); return(0); }}},
{2,{MOD_ALT | MOD_NOREPEAT, 0x51, "ALT+Q", [](void* p) {if (MessageBoxW(NULL, L"退出软件?", L"退出消息", MB_OKCANCEL) == IDOK) { ((HotKeyWnd*)p)->UnRegisterHotKeys(); return(1); } return(0); }}},
},},
};
bool RegisterHotKeys()
{
for (auto& mit : m_mmHotKey)
{
for (auto& mmit : mit.second)
{
if (!RegisterHotKey(mit.first, mmit.first, mmit.second.fsModifiers, mmit.second.vk))
{
LogOut("Hotkey ", mmit.second.desc, " registered false. Error id=.", GetLastError()) << std::endl;
return false;
}
}
}
return true;
}
int CallBackHotKeys(HWND hWnd, INT nHotKeyId, void* pUserData) {
if (m_mmHotKey.find(hWnd) != m_mmHotKey.end() && m_mmHotKey.at(hWnd).find(nHotKeyId) != m_mmHotKey.at(hWnd).end())
{
return m_mmHotKey.at(hWnd).at(nHotKeyId).cb(pUserData);
}
return (-1);
}
void UnRegisterHotKeys()
{
for (auto& mit : m_mmHotKey)
{
for (auto& mmit : mit.second)
{
UnregisterHotKey(mit.first, mmit.first);
}
}
}
};
############################
main.cpp中调用
int main(int argc, char** argv)
{
MSG msg = { 0 };
HotKeyWnd hkw = {};
if (hkw.RegisterHotKeys() == false)
{
LogOut("注册热键失败") << std::endl;
}
else
{
LogOut("\"ALT+E\" - 执行任务\t\"ALT+Q\" - 退出脚本") << std::endl;
while (GetMessageW(&msg, NULL, 0, 0) != 0)
{
if (msg.message == WM_HOTKEY)
{
if (hkw.CallBackHotKeys(NULL, msg.wParam, &hkw) > 0)
{
break;
}
}
}
}
return (int)(msg.wParam);
}
其它常用工具函数集合
__inline static LPCWSTR getAppPath()
{
static WCHAR CFGL_APP_PATH[MAX_PATH] = { 0 };
if (!(*CFGL_APP_PATH))
{
DWORD dwLen = GetModuleFileNameW(NULL, CFGL_APP_PATH, MAX_PATH);
for (--dwLen; dwLen > 0; dwLen--)
{
if (CFGL_APP_PATH[dwLen] == L'\\')
{
memset(&CFGL_APP_PATH[dwLen + 1], 0, MAX_PATH - dwLen);
break;
}
}
}
return CFGL_APP_PATH;
}
__inline static LPCWSTR getAppName()
{
static WCHAR CFGL_APP_NAME[MAX_PATH] = { 0 };
if (!(*CFGL_APP_NAME))
{
DWORD dwLen = GetModuleFileNameW(NULL, CFGL_APP_NAME, MAX_PATH);
for (--dwLen; dwLen > 0; dwLen--)
{
if (CFGL_APP_NAME[dwLen] == L'\\')
{
memcpy(&CFGL_APP_NAME[0], &CFGL_APP_NAME[dwLen + 1], MAX_PATH - dwLen);
memset(&CFGL_APP_NAME[dwLen + 1], 0, dwLen);
break;
}
}
}
return CFGL_APP_NAME;
}
__inline static std::wstring UTF8_2_W(const std::string& s)
{
std::wstring ws(::MultiByteToWideChar(CP_UTF8, 0, s.data(), -1, NULL, 0), L'\0');
::MultiByteToWideChar(CP_UTF8, 0, s.data(), -1, (LPWSTR)ws.data(), (INT)ws.size());
return ws;
}
__inline static std::string W_2_UTF8(const std::wstring& ws)
{
std::string s(::WideCharToMultiByte(CP_UTF8, 0, ws.data(), -1, NULL, 0, NULL, NULL), '\0');
::WideCharToMultiByte(CP_UTF8, 0, ws.data(), -1, (LPSTR)s.data(), (INT)s.size(), NULL, NULL);
return s;
}
__inline static std::wstring A_2_W(const std::string& s)
{
std::wstring ws(::MultiByteToWideChar(CP_ACP, 0, s.data(), -1, NULL, 0), L'\0');
::MultiByteToWideChar(CP_ACP, 0, s.data(), -1, (LPWSTR)ws.data(), (INT)ws.size());
return ws;
}
__inline static std::string W_2_A(const std::wstring& ws)
{
std::string s(::WideCharToMultiByte(CP_ACP, 0, ws.data(), -1, NULL, 0, NULL, NULL), '\0');
::WideCharToMultiByte(CP_ACP, 0, ws.data(), -1, (LPSTR)s.data(), (INT)s.size(), NULL, NULL);
return s;
}
__inline static std::string UTF8_2_A(const std::string& s)
{
return W_2_A(UTF8_2_W(s));
}
__inline static std::string A_2_UTF8(const std::string& s)
{
return W_2_UTF8(A_2_W(s));
}
typedef enum Encode { ANSI = 1, UTF16_LE, UTF16_BE, UTF8_BOM, UTF8 }Encode;
__inline static Encode IsUtf8Data(const uint8_t* data, size_t size)
{
bool bAnsi = true;
uint8_t ch = 0x00;
int32_t nBytes = 0;
for (auto i = 0; i < (int)size; i++)
{
ch = *(data + i);
if ((ch & 0x80) != 0x00)
{
bAnsi = false;
}
if (nBytes == 0)
{
if (ch >= 0x80)
{
if (ch >= 0xFC && ch <= 0xFD)
{
nBytes = 6;
}
else if (ch >= 0xF8)
{
nBytes = 5;
}
else if (ch >= 0xF0)
{
nBytes = 4;
}
else if (ch >= 0xE0)
{
nBytes = 3;
}
else if (ch >= 0xC0)
{
nBytes = 2;
}
else
{
return Encode::ANSI;
}
nBytes--;
}
}
else
{
if ((ch & 0xC0) != 0x80)
{
return Encode::ANSI;
}
nBytes--;
}
}
if (nBytes > 0 || bAnsi)
{
return Encode::ANSI;
}
return Encode::UTF8;
}
__inline static Encode DetectEncode(const uint8_t* data, size_t size)
{
if (size > 2 && data[0] == 0xFF && data[1] == 0xFE)
{
return Encode::UTF16_LE;
}
else if (size > 2 && data[0] == 0xFE && data[1] == 0xFF)
{
return Encode::UTF16_BE;
}
else if (size > 3 && data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)
{
return Encode::UTF8_BOM;
}
else
{
return IsUtf8Data(data, size);
}
}
__inline static const std::string& string_replace_all_after_pos(std::string& strData, const std::string& strDst, const std::string& strSrc, std::string::size_type stPos = 0)
{
while ((stPos = strData.find(strSrc, stPos)) != std::string::npos)
{
strData.replace(stPos, strSrc.length(), strDst);
stPos += strDst.length();
}
return strData;
}
__inline static const std::string& string_replace_all(std::string& strData, const std::string& strDst, const std::string& strSrc)
{
size_t pos = 0;
while ((pos = strData.find(strSrc)) != std::string::npos)
{
strData.replace(pos, strSrc.length(), strDst);
}
return strData;
}
__inline static const std::wstring& wstring_replace_all_after_pos(std::wstring& strData, const std::wstring& strDst, const std::wstring& strSrc, std::wstring::size_type stPos = 0)
{
while ((stPos = strData.find(strSrc, stPos)) != std::wstring::npos)
{
strData.replace(stPos, strSrc.length(), strDst);
stPos += strDst.length();
}
return strData;
}
__inline static const std::wstring& wstring_replace_all(std::wstring& strData, const std::wstring& strDst, const std::wstring& strSrc)
{
size_t pos = 0;
while ((pos = strData.find(strSrc)) != std::wstring::npos)
{
strData.replace(pos, strSrc.length(), strDst);
}
return strData;
}