Доброго всем впемени суток, я засубклассил окно, в окне есть области, которые я хочу сделать кликабельными, в этих местах ,например, текст напечатан мной. Функции что должны выполняться висят на горячих клавишах в приложении, при клике в области текста я вызываю keybd_event нажимая и отжимая нужную кнопку, но программа реагирует через раз в лучшем случае, щас даже вызываю по три раза группы из keybd_event. Вопрос как еще имитировать нажатие клавиши, CallWindowProc? не пашет почему то. Код (Text): LRESULT CALLBACK WndProc(IN HWND hWnd,IN UINT msg,IN WPARAM wParam,IN LPARAM lParam) { POINT xy; if (!b_connected) return true; switch (msg) { case WM_LBUTTONDOWN: xy.x=LOWORD(lParam); xy.y=HIWORD(lParam); if (InRect(btnRet,xy )) { b_retPressed=true; } break; case WM_LBUTTONUP: xy.x=LOWORD(lParam); xy.y=HIWORD(lParam); switch(b_inSelector) { case true: if (InRect(btn1,xy)) { keybd_event(VK_NUMPAD3,NULL,NULL,NULL); keybd_event(VK_NUMPAD3,NULL,KEYEVENTF_KEYUP,NULL); keybd_event(VK_NUMPAD3,NULL,NULL,NULL); keybd_event(VK_NUMPAD3,NULL,KEYEVENTF_KEYUP,NULL); keybd_event(VK_NUMPAD3,NULL,NULL,NULL); keybd_event(VK_NUMPAD3,NULL,KEYEVENTF_KEYUP,NULL); }
WndProc одна на оба окна, да? ну вот значит дай её полностью (только опиши что в коде какому полю формы соответствует)
Окно одно. Код (Text): LRESULT CALLBACK WndProc(IN HWND hWnd,IN UINT msg,IN WPARAM wParam,IN LPARAM lParam) { POINT xy; INPUT inpt[1]; KEYBDINPUT kinpt[1]; if (!b_connected) return true; switch (msg) { case WM_LBUTTONDOWN: xy.x=LOWORD(lParam); xy.y=HIWORD(lParam); if (InRect(btnRet,xy )) { b_retPressed=true; } break; case WM_LBUTTONUP: xy.x=LOWORD(lParam); xy.y=HIWORD(lParam); switch(b_inSelector) { case true: if (InRect(btn1,xy)) { b_inSelector=false; kinpt[0].wVk=VK_NUMPAD3; kinpt[0].time=NULL; kinpt[0].dwExtraInfo=NULL; kinpt[0].wScan=NULL; kinpt[0].dwFlags=NULL; inpt[0].type=INPUT_KEYBOARD; inpt[0].ki=kinpt[0]; memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0])); kinpt[1].dwFlags=KEYEVENTF_KEYUP; SendInput(2,&inpt[0],sizeof(inpt[0])); } if (InRect(btn3,xy)) { b_inSelector=false; kinpt[0].wVk=VK_NUMPAD7; kinpt[0].time=NULL; kinpt[0].dwExtraInfo=NULL; kinpt[0].wScan=NULL; kinpt[0].dwFlags=NULL; inpt[0].type=INPUT_KEYBOARD; inpt[0].ki=kinpt[0]; memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0])); kinpt[1].dwFlags=KEYEVENTF_KEYUP; SendInput(2,&inpt[0],sizeof(inpt[0])); } if (InRect(btn5,xy)) { b_inSelector=false; kinpt[0].wVk=VK_NUMPAD1; kinpt[0].time=NULL; kinpt[0].dwExtraInfo=NULL; kinpt[0].wScan=NULL; kinpt[0].dwFlags=NULL; inpt[0].type=INPUT_KEYBOARD; inpt[0].ki=kinpt[0]; memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0])); kinpt[1].dwFlags=KEYEVENTF_KEYUP; SendInput(2,&inpt[0],sizeof(inpt[0])); } if (InRect(btn7,xy)) { b_inSelector=false; kinpt[0].wVk=VK_NUMPAD5; kinpt[0].time=NULL; kinpt[0].dwExtraInfo=NULL; kinpt[0].wScan=NULL; kinpt[0].dwFlags=NULL; inpt[0].type=INPUT_KEYBOARD; inpt[0].ki=kinpt[0]; memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0])); kinpt[1].dwFlags=KEYEVENTF_KEYUP; SendInput(2,&inpt[0],sizeof(inpt[0])); } if (InRect(btn9,xy)) { b_inSelector=false; kinpt[0].wVk=VK_NUMPAD9; kinpt[0].time=NULL; kinpt[0].dwExtraInfo=NULL; kinpt[0].wScan=NULL; kinpt[0].dwFlags=NULL; inpt[0].type=INPUT_KEYBOARD; inpt[0].ki=kinpt[0]; memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0])); kinpt[1].dwFlags=KEYEVENTF_KEYUP; SendInput(2,&inpt[0],sizeof(inpt[0])); } if (InRect(btnRet,xy)) { b_retPressed=false; kinpt[0].wVk=VK_RETURN; kinpt[0].time=1; kinpt[0].dwExtraInfo=NULL; kinpt[0].wScan=NULL; kinpt[0].dwFlags=NULL; inpt[0].type=INPUT_KEYBOARD; inpt[0].ki=kinpt[0]; memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0])); kinpt[1].dwFlags=KEYEVENTF_KEYUP; BlockInput(TRUE); SendInput(2,&inpt[0],sizeof(inpt[0])); BlockInput(FALSE); } break; case false: break; default: break; } break; case WM_KEYDOWN: if (wParam==VK_DIVIDE) b_inSelector=true; break; default: break; } return CallWindowProc((WNDPROC)dw_OldProc,hWnd,msg,wParam,lParam); } Код (Text): dw_OldProc=SetWindowLong(ret,GWL_WNDPROC,(long)WndProc);
SendInput отрабатывает только 1 раз, потом приходится физически жать на кнопку, потом опять раз отрабатывает.
Код (Text): __forceinline bool InRect(RECT rc,POINT pt) { if (min(rc.left,pt.x)==rc.left && min(rc.right,pt.x)==pt.x && min(rc.top,pt.y)==rc.top && min(rc.bottom,pt.y)==pt.y) return true; return false; } Код (Text): #define min(a, b) (((a) < (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b))
Код (Text): b_retPressed=false; kinpt[0].wVk=VK_RETURN; kinpt[0].time=NULL; kinpt[0].dwExtraInfo=NULL; kinpt[0].wScan=NULL; kinpt[0].dwFlags=NULL; inpt[0].type=INPUT_KEYBOARD; inpt[0].ki=kinpt[0]; memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0])); kinpt[1].dwFlags=KEYEVENTF_KEYUP; inpt[1].type=INPUT_KEYBOARD; inpt[1].ki=kinpt[1]; SendInput(2,&inpt[0],sizeof(inpt[0])); так быть должно везде, но результат тот же.
void GenerateKey ( int vk , BOOL bExtended) { KEYBDINPUT kb={0}; INPUT Input={0}; // generate down if ( bExtended ) kb.dwFlags = KEYEVENTF_EXTENDEDKEY; kb.wVk = vk; Input.type = INPUT_KEYBOARD; Input.ki = kb; ::SendInput(1,&Input,sizeof(Input)); // generate up ::ZeroMemory(&kb,sizeof(KEYBDINPUT)); ::ZeroMemory(&Input,sizeof(INPUT)); kb.dwFlags = KEYEVENTF_KEYUP; if ( bExtended ) kb.dwFlags |= KEYEVENTF_EXTENDEDKEY; kb.wVk = vk; Input.type = INPUT_KEYBOARD; Input.ki = kb; ::SendInput(1,&Input,sizeof(Input)); } Тоже отрабатывает через раз( Косяк где то глубже, где то я косячу в процедуре окна%(
Может, задержечку бы надо в пару-тройку сотен миллисекунд промеж двух SendInput? А то я уже встречал такую беду - то "нажатая" кнопка залипнет, то вообще ничего не произойдёт, и все эти беды случались когда задержка межуд нажатием и отпусканием была меньше 100мс.
вот что есть: Код (Text): void GenerateKey ( WORD vk) { KEYBDINPUT kinpt={0}; INPUT inpt={0}; // generate down inpt.type=INPUT_KEYBOARD; kinpt.wVk=vk; kinpt.time=NULL; kinpt.dwExtraInfo=NULL; kinpt.wScan=NULL; kinpt.dwFlags=NULL; inpt.ki=kinpt; SendInput(1,&inpt,sizeof(inpt)); kinpt.dwFlags=KEYEVENTF_KEYUP; Sleep(100); SendInput(1,&inpt,sizeof(inpt)); return; } void GenerateKbdEvent (WORD vk) { keybd_event(vk,NULL,NULL,NULL); Sleep(100); keybd_event(vk,NULL,KEYEVENTF_KEYUP,NULL); return; } void PostVkeyMessage(HWND hWnd,WORD vk) { PostMessage(hWnd,WM_KEYDOWN,VK_RETURN,NULL); Sleep(100); PostMessage(hWnd,WM_KEYUP,VK_RETURN,NULL); return; } void SendVkeyMessage(HWND hWnd,WORD vk) { SendMessage(hWnd,WM_KEYDOWN,VK_RETURN,NULL); Sleep(100); SendMessage(hWnd,WM_KEYUP,VK_RETURN,NULL); return; }