имитация нажатия клавиши на клавиатуре

Тема в разделе "WASM.WIN32", создана пользователем punxer, 9 май 2010.

  1. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Доброго всем впемени суток, я засубклассил окно, в окне есть области, которые я хочу сделать кликабельными, в этих местах ,например, текст напечатан мной. Функции что должны выполняться висят на горячих клавишах в приложении, при клике в области текста я вызываю keybd_event нажимая и отжимая нужную кнопку, но программа реагирует через раз в лучшем случае, щас даже вызываю по три раза группы из keybd_event.
    Вопрос как еще имитировать нажатие клавиши, CallWindowProc? не пашет почему то.
    Код (Text):
    1. LRESULT CALLBACK WndProc(IN HWND hWnd,IN UINT msg,IN WPARAM wParam,IN LPARAM lParam)
    2. {
    3.  
    4.     POINT xy;
    5.  
    6.     if (!b_connected)
    7.         return true;
    8.    
    9.     switch (msg)
    10.     {
    11.         case WM_LBUTTONDOWN:
    12.             xy.x=LOWORD(lParam);
    13.             xy.y=HIWORD(lParam);
    14.            
    15.             if (InRect(btnRet,xy ))
    16.             {
    17.                 b_retPressed=true;
    18.             }
    19.  
    20.             break;
    21.  
    22.         case WM_LBUTTONUP:
    23.             xy.x=LOWORD(lParam);
    24.             xy.y=HIWORD(lParam);
    25.            
    26.             switch(b_inSelector)
    27.             {
    28.             case true:
    29.  
    30.                 if (InRect(btn1,xy))
    31.                 {
    32.    
    33.                     keybd_event(VK_NUMPAD3,NULL,NULL,NULL);
    34.                     keybd_event(VK_NUMPAD3,NULL,KEYEVENTF_KEYUP,NULL);
    35.                     keybd_event(VK_NUMPAD3,NULL,NULL,NULL);
    36.                     keybd_event(VK_NUMPAD3,NULL,KEYEVENTF_KEYUP,NULL);
    37.                     keybd_event(VK_NUMPAD3,NULL,NULL,NULL);
    38.                     keybd_event(VK_NUMPAD3,NULL,KEYEVENTF_KEYUP,NULL);
    39.  
    40.                    
    41.                 }
     
  2. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    спасибо
     
  3. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    ну может есть мысли какие нибудь?
     
  4. vover

    vover Владимир

    Публикаций:
    0
    Регистрация:
    21 авг 2008
    Сообщения:
    202
  5. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    vover
    себе же в перехваченную процедуру окна?
     
  6. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    тут кто-то не знает о DefWindowProc? )
     
  7. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Comer_

    Но отнють не она обрабатывает нажатия кнопок, а как раз та, что засубкласена.
     
  8. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    про DefWindowProc знают)
     
  9. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    WndProc одна на оба окна, да?
    ну вот значит дай её полностью (только опиши что в коде какому полю формы соответствует)
     
  10. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Окно одно.
    Код (Text):
    1. LRESULT CALLBACK WndProc(IN HWND hWnd,IN UINT msg,IN WPARAM wParam,IN LPARAM lParam)
    2. {
    3.  
    4.     POINT xy;
    5.     INPUT inpt[1];
    6.     KEYBDINPUT kinpt[1];
    7.  
    8.     if (!b_connected)
    9.         return true;
    10.    
    11.     switch (msg)
    12.     {
    13.         case WM_LBUTTONDOWN:
    14.             xy.x=LOWORD(lParam);
    15.             xy.y=HIWORD(lParam);
    16.            
    17.             if (InRect(btnRet,xy ))
    18.             {
    19.                 b_retPressed=true;
    20.             }
    21.  
    22.             break;
    23.  
    24.         case WM_LBUTTONUP:
    25.             xy.x=LOWORD(lParam);
    26.             xy.y=HIWORD(lParam);
    27.            
    28.             switch(b_inSelector)
    29.             {
    30.             case true:
    31.  
    32.                 if (InRect(btn1,xy))
    33.                 {
    34.  
    35.                     b_inSelector=false;
    36.                     kinpt[0].wVk=VK_NUMPAD3;
    37.                     kinpt[0].time=NULL;
    38.                     kinpt[0].dwExtraInfo=NULL;
    39.                     kinpt[0].wScan=NULL;
    40.                     kinpt[0].dwFlags=NULL;
    41.                     inpt[0].type=INPUT_KEYBOARD;
    42.                     inpt[0].ki=kinpt[0];
    43.                     memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0]));
    44.                     kinpt[1].dwFlags=KEYEVENTF_KEYUP;
    45.                     SendInput(2,&inpt[0],sizeof(inpt[0]));
    46.  
    47.                    
    48.                 }
    49.  
    50.                 if (InRect(btn3,xy))
    51.                 {
    52.  
    53.                     b_inSelector=false;
    54.                    
    55.                     kinpt[0].wVk=VK_NUMPAD7;
    56.                     kinpt[0].time=NULL;
    57.                     kinpt[0].dwExtraInfo=NULL;
    58.                     kinpt[0].wScan=NULL;
    59.                     kinpt[0].dwFlags=NULL;
    60.                     inpt[0].type=INPUT_KEYBOARD;
    61.                     inpt[0].ki=kinpt[0];
    62.                     memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0]));
    63.                     kinpt[1].dwFlags=KEYEVENTF_KEYUP;
    64.                     SendInput(2,&inpt[0],sizeof(inpt[0]));
    65.                    
    66.                 }
    67.                 if (InRect(btn5,xy))
    68.                 {
    69.                    
    70.  
    71.                     b_inSelector=false;
    72.  
    73.                     kinpt[0].wVk=VK_NUMPAD1;
    74.                     kinpt[0].time=NULL;
    75.                     kinpt[0].dwExtraInfo=NULL;
    76.                     kinpt[0].wScan=NULL;
    77.                     kinpt[0].dwFlags=NULL;
    78.                     inpt[0].type=INPUT_KEYBOARD;
    79.                     inpt[0].ki=kinpt[0];
    80.                     memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0]));
    81.                     kinpt[1].dwFlags=KEYEVENTF_KEYUP;
    82.                     SendInput(2,&inpt[0],sizeof(inpt[0]));
    83.                 }
    84.                 if (InRect(btn7,xy))
    85.                 {
    86.  
    87.                     b_inSelector=false;
    88.  
    89.                     kinpt[0].wVk=VK_NUMPAD5;
    90.                     kinpt[0].time=NULL;
    91.                     kinpt[0].dwExtraInfo=NULL;
    92.                     kinpt[0].wScan=NULL;
    93.                     kinpt[0].dwFlags=NULL;
    94.                     inpt[0].type=INPUT_KEYBOARD;
    95.                     inpt[0].ki=kinpt[0];
    96.                     memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0]));
    97.                     kinpt[1].dwFlags=KEYEVENTF_KEYUP;
    98.                     SendInput(2,&inpt[0],sizeof(inpt[0]));
    99.                 }
    100.  
    101.                 if (InRect(btn9,xy))
    102.                 {
    103.  
    104.                     b_inSelector=false;
    105.  
    106.                     kinpt[0].wVk=VK_NUMPAD9;
    107.                     kinpt[0].time=NULL;
    108.                     kinpt[0].dwExtraInfo=NULL;
    109.                     kinpt[0].wScan=NULL;
    110.                     kinpt[0].dwFlags=NULL;
    111.                     inpt[0].type=INPUT_KEYBOARD;
    112.                     inpt[0].ki=kinpt[0];
    113.                     memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0]));
    114.                     kinpt[1].dwFlags=KEYEVENTF_KEYUP;
    115.                     SendInput(2,&inpt[0],sizeof(inpt[0]));
    116.                    
    117.                 }
    118.                 if (InRect(btnRet,xy))
    119.                 {
    120.                     b_retPressed=false;
    121.                     kinpt[0].wVk=VK_RETURN;
    122.                     kinpt[0].time=1;
    123.                     kinpt[0].dwExtraInfo=NULL;
    124.                     kinpt[0].wScan=NULL;
    125.                     kinpt[0].dwFlags=NULL;
    126.                     inpt[0].type=INPUT_KEYBOARD;
    127.                     inpt[0].ki=kinpt[0];
    128.                     memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0]));
    129.                     kinpt[1].dwFlags=KEYEVENTF_KEYUP;
    130.                     BlockInput(TRUE);
    131.                     SendInput(2,&inpt[0],sizeof(inpt[0]));
    132.                     BlockInput(FALSE);
    133.  
    134.                 }
    135.                
    136.                 break;
    137.             case false:
    138.            
    139.                 break;
    140.             default:
    141.                 break;
    142.            
    143.             }
    144.            
    145.  
    146.             break;
    147.  
    148.         case WM_KEYDOWN:
    149.             if (wParam==VK_DIVIDE)
    150.                 b_inSelector=true;
    151.  
    152.             break;
    153.         default:
    154.             break;
    155.  
    156.  
    157.     }
    158.     return CallWindowProc((WNDPROC)dw_OldProc,hWnd,msg,wParam,lParam);
    159. }
    Код (Text):
    1. dw_OldProc=SetWindowLong(ret,GWL_WNDPROC,(long)WndProc);
     
  11. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    SendInput отрабатывает только 1 раз, потом приходится физически жать на кнопку, потом опять раз отрабатывает.
     
  12. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. __forceinline bool InRect(RECT rc,POINT pt)
    2. {
    3.     if (min(rc.left,pt.x)==rc.left &&
    4.         min(rc.right,pt.x)==pt.x   &&
    5.         min(rc.top,pt.y)==rc.top   &&
    6.         min(rc.bottom,pt.y)==pt.y)
    7.             return true;
    8.  
    9.     return false;
    10. }
    Код (Text):
    1. #define min(a, b)  (((a) < (b)) ? (a) : (b))
    2. #define max(a, b)  (((a) > (b)) ? (a) : (b))
     
  13. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    InRect все правильно определяет!
     
  14. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1.                     b_retPressed=false;
    2.                     kinpt[0].wVk=VK_RETURN;
    3.                     kinpt[0].time=NULL;
    4.                     kinpt[0].dwExtraInfo=NULL;
    5.                     kinpt[0].wScan=NULL;
    6.                     kinpt[0].dwFlags=NULL;
    7.                     inpt[0].type=INPUT_KEYBOARD;
    8.                     inpt[0].ki=kinpt[0];
    9.  
    10.                     memcpy(&kinpt[1],&kinpt[0],sizeof(kinpt[0]));
    11.                     kinpt[1].dwFlags=KEYEVENTF_KEYUP;
    12.                     inpt[1].type=INPUT_KEYBOARD;
    13.                     inpt[1].ki=kinpt[1];
    14.  
    15.                     SendInput(2,&inpt[0],sizeof(inpt[0]));
    так быть должно везде, но результат тот же.
     
  15. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    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));
    }

    Тоже отрабатывает через раз( Косяк где то глубже, где то я косячу в процедуре окна%(
     
  16. MikDay

    MikDay New Member

    Публикаций:
    0
    Регистрация:
    5 май 2005
    Сообщения:
    32
    Адрес:
    Minsk
    Попробуйте PostMessage(hYourWnd, WM_KEYDOWN, ....)
     
  17. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Может, задержечку бы надо в пару-тройку сотен миллисекунд промеж двух SendInput? А то я уже встречал такую беду - то "нажатая" кнопка залипнет, то вообще ничего не произойдёт, и все эти беды случались когда задержка межуд нажатием и отпусканием была меньше 100мс.
     
  18. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    MikDayCyberManiac
    Спасибо, попробуемс.
     
  19. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    непашет((
     
  20. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    вот что есть:
    Код (Text):
    1. void GenerateKey ( WORD vk)
    2. {
    3.     KEYBDINPUT  kinpt={0};
    4.     INPUT       inpt={0};
    5.     // generate down
    6.     inpt.type=INPUT_KEYBOARD;
    7.     kinpt.wVk=vk;
    8.     kinpt.time=NULL;
    9.     kinpt.dwExtraInfo=NULL;
    10.     kinpt.wScan=NULL;
    11.     kinpt.dwFlags=NULL;
    12.     inpt.ki=kinpt;
    13.  
    14.     SendInput(1,&inpt,sizeof(inpt));
    15.     kinpt.dwFlags=KEYEVENTF_KEYUP;
    16.     Sleep(100);
    17.     SendInput(1,&inpt,sizeof(inpt));
    18.     return;
    19. }
    20.  
    21.  
    22. void GenerateKbdEvent (WORD vk)
    23. {
    24.     keybd_event(vk,NULL,NULL,NULL);
    25.     Sleep(100);
    26.     keybd_event(vk,NULL,KEYEVENTF_KEYUP,NULL);
    27.  
    28.     return;
    29. }
    30.  
    31.  
    32. void PostVkeyMessage(HWND hWnd,WORD vk)
    33. {
    34.     PostMessage(hWnd,WM_KEYDOWN,VK_RETURN,NULL);
    35.     Sleep(100);
    36.     PostMessage(hWnd,WM_KEYUP,VK_RETURN,NULL);
    37.  
    38.     return;
    39. }
    40.  
    41. void SendVkeyMessage(HWND hWnd,WORD vk)
    42. {
    43.     SendMessage(hWnd,WM_KEYDOWN,VK_RETURN,NULL);
    44.     Sleep(100);
    45.     SendMessage(hWnd,WM_KEYUP,VK_RETURN,NULL);
    46.  
    47.     return;
    48. }