|
|
@@ -11,6 +11,19 @@
|
|
|
|
|
|
#include <atltypes.h>
|
|
|
|
|
|
+void RegKeyboardRawInput(HWND hWnd)
|
|
|
+{
|
|
|
+ RAWINPUTDEVICE rawInputDevice[1];
|
|
|
+ rawInputDevice[0].usUsagePage = 0x01;//设备类
|
|
|
+ rawInputDevice[0].usUsage = 0x06;//设备类内的具体设备
|
|
|
+ rawInputDevice[0].dwFlags = RIDEV_INPUTSINK;//意味着即使窗口失去焦点位置,仍然会一直接收输入消息
|
|
|
+ rawInputDevice[0].hwndTarget = hWnd;
|
|
|
+ if (RegisterRawInputDevices(rawInputDevice, 1, sizeof(rawInputDevice[0])) == FALSE)
|
|
|
+ {
|
|
|
+ printf("RegisterRawInputDevices failed");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void CValueWnd::Notify(TNotifyUI& msg)
|
|
|
{
|
|
|
if(msg.sType == _T("click"))
|
|
|
@@ -75,6 +88,8 @@ void CValueWnd::Init()
|
|
|
|
|
|
//开始启动监听
|
|
|
RestartWatch();
|
|
|
+
|
|
|
+ RegKeyboardRawInput(m_hWnd);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -429,6 +444,132 @@ LRESULT CValueWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|
|
return HTCLIENT;
|
|
|
}
|
|
|
|
|
|
+LRESULT CValueWnd::OnInput(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
|
+{
|
|
|
+ UINT dwSize = 0;
|
|
|
+ GetRawInputData((HRAWINPUT)lParam, (UINT)RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));//取数据,第一次调用函数将获取需要的字节大小
|
|
|
+ LPBYTE lpbBuffer = new BYTE[dwSize];//分配指定的缓冲区大小
|
|
|
+ GetRawInputData((HRAWINPUT)lParam, (UINT)RID_INPUT, (LPVOID)lpbBuffer, (PUINT)&dwSize, (UINT)sizeof(RAWINPUTHEADER));//第二次调用获取原始输入数据,读入lpbBuffer
|
|
|
+
|
|
|
+ RAWINPUT * raw = (RAWINPUT *)lpbBuffer;
|
|
|
+ if (raw->header.dwType == RIM_TYPEKEYBOARD)//这里可以截获所有键盘信息,如需区分不同的键盘输入信息,可以通过设备句柄判断。
|
|
|
+ {
|
|
|
+ if (raw->data.keyboard.Message == WM_KEYDOWN)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ else if (raw->data.keyboard.Message == WM_KEYUP)
|
|
|
+ {
|
|
|
+ char keytext[10] = { 0 };
|
|
|
+ BYTE state[256] = { 0 };
|
|
|
+
|
|
|
+ //通过虚拟键盘码得到名字
|
|
|
+ ToAscii(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, state, (LPWORD)keytext, 0);
|
|
|
+
|
|
|
+ string a = keytext;
|
|
|
+
|
|
|
+ if (raw->data.keyboard.VKey >= 48 && raw->data.keyboard.VKey <= 57)
|
|
|
+ {
|
|
|
+ //只考虑数字
|
|
|
+ if (m_is_start_catch == false)
|
|
|
+ {
|
|
|
+ m_is_start_catch = true;
|
|
|
+
|
|
|
+ m_catch_string = "";
|
|
|
+
|
|
|
+ char keytext[10] = { 0 };
|
|
|
+ BYTE state[256] = { 0 };
|
|
|
+
|
|
|
+ //通过虚拟键盘码得到名字
|
|
|
+ ToAscii(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, state, (LPWORD)keytext, 0);
|
|
|
+
|
|
|
+ m_catch_string += string(keytext);
|
|
|
+
|
|
|
+ m_last_catch_clock = clock();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //已经是在抓取过程中了
|
|
|
+ clock_t now = clock();
|
|
|
+
|
|
|
+ double total_t = (double)(now - m_last_catch_clock) / CLOCKS_PER_SEC;
|
|
|
+ if (total_t > 0.05)
|
|
|
+ {
|
|
|
+ //如果超过了50ms,说明是人工输入的了,就重置所有状态
|
|
|
+ m_is_start_catch = false;
|
|
|
+
|
|
|
+ m_catch_string = "";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ char keytext[10] = { 0 };
|
|
|
+ BYTE state[256] = { 0 };
|
|
|
+
|
|
|
+ //通过虚拟键盘码得到名字
|
|
|
+ ToAscii(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, state, (LPWORD)keytext, 0);
|
|
|
+
|
|
|
+ m_catch_string += string(keytext);
|
|
|
+
|
|
|
+ m_last_catch_clock = clock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (raw->data.keyboard.VKey == 13)
|
|
|
+ {
|
|
|
+ //enter
|
|
|
+ std::string last = m_catch_string;
|
|
|
+
|
|
|
+ bool is_fukuanma = false;
|
|
|
+ //判断是不是正常的付款码格式
|
|
|
+ if (last.find("10") == 0 \
|
|
|
+ || last.find("11") == 0 \
|
|
|
+ || last.find("12") == 0 \
|
|
|
+ || last.find("13") == 0 \
|
|
|
+ || last.find("14") == 0 \
|
|
|
+ || last.find("15") == 0)
|
|
|
+ {
|
|
|
+ //微信付款码
|
|
|
+ is_fukuanma = true;
|
|
|
+ }
|
|
|
+ else if (last.find("25") == 0 \
|
|
|
+ || last.find("26") == 0 \
|
|
|
+ || last.find("27") == 0 \
|
|
|
+ || last.find("28") == 0 \
|
|
|
+ || last.find("29") == 0 \
|
|
|
+ || last.find("30") == 0)
|
|
|
+ {
|
|
|
+ //支付宝付款码
|
|
|
+ is_fukuanma = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (is_fukuanma)
|
|
|
+ {
|
|
|
+ //得到一个合适的付款码
|
|
|
+ if (m_is_show_shoukuan == false)
|
|
|
+ {
|
|
|
+ ShowShoukuan();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //不管是不是正常的付款码,收到enter后,这里都清空重来
|
|
|
+ m_is_start_catch = false;
|
|
|
+ m_catch_string = "";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ //这种直接忽略,重新开始
|
|
|
+ m_is_start_catch = false;
|
|
|
+
|
|
|
+ m_catch_string = "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ delete[] lpbBuffer;
|
|
|
+
|
|
|
+ bHandled = true;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
LRESULT CValueWnd::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
|
{
|
|
|
pMenu->ShowWindow(false);
|
|
|
@@ -550,6 +691,9 @@ LRESULT CValueWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
lRes = OnHotKey(uMsg, wParam, lParam, bHandled);
|
|
|
break;
|
|
|
|
|
|
+ case WM_INPUT:
|
|
|
+ lRes = OnInput(uMsg, wParam, lParam, bHandled);
|
|
|
+ break;
|
|
|
default:
|
|
|
bHandled = FALSE;
|
|
|
}
|
|
|
@@ -604,6 +748,11 @@ void CValueWnd::ShowShoukuan()
|
|
|
pShoukuanWnd->InitMoney(m_watchValue);
|
|
|
}
|
|
|
|
|
|
+ if (m_is_start_catch && m_catch_string.length() == 18)
|
|
|
+ {
|
|
|
+ pShoukuanWnd->InitFukuanma(m_catch_string);
|
|
|
+ }
|
|
|
+
|
|
|
UINT ret = pShoukuanWnd->ShowModal();
|
|
|
|
|
|
m_is_show_shoukuan = false;
|