Как програмно имитировать нажатие клавиши?

Тема в разделе "WASM.BEGINNERS", создана пользователем hakeem, 11 авг 2008.

  1. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Объясните пожалуйста, как программно симитировать нажатие какой либо клавиши?
     
  2. Subrealist

    Subrealist Member

    Публикаций:
    0
    Регистрация:
    17 июл 2006
    Сообщения:
    134
    Почитай про эту функцию из user32.
    VOID keybd_event( BYTE bVk,
    BYTE bScan,
    DWORD dwFlags,
    PTR dwExtraInfo
    );

    ( При помощи неё можно даже переключать светодиоды на клавиатуре :))

    и ещё про эту

    UINT SendInput( UINT nInputs,
    LPINPUT pInputs,
    int cbSize
    );
     
  3. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    Subrealist

    Спасибо...
     
  4. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    keybd_event устаревшая команда, МСДН рекомендует использовать SendInput.
     
  5. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    beginner

    Чем она лучше и как првильно вызвать эту функцию?
     
  6. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    hakeem спроси у МСДН
     
  7. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    hakeem
    UINT SendInput (
    UINT nInputs,
    LPINPUT pInputs,
    int cbSize
    );

    nInputs - кол-во действий, которые необходимо выполнить, например как движение мышью или нажатия клавиш. (или кол-во структур в массиве. см. следующий параметр.) Если одно действие нужно выполнить - то пишешь 1.
    pInputs - указатель на структуру INPUT или на массив структур INPUT, где описываешь то (те) действие(я), которые нужно выполнить, такие как, движение мыши, нажатия кнопок мыши, скролла, нажатия кнопок на клаве и прочее. Там еще поидее можно выставить задержку между этими действиями, но судя по всему эта фишка не пашет.
    cbSize - размер структуры в байтах.

    А как вызвать? формируешь структуры мыши и/или клавы, где указываешь что тебе нужно сделать, описываешь структуру INPUT и вызываешь функцию SendInput. Ниче сложного.

    И кстати да, МСДН в этом плане рулит :)
     
  8. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    beginner

    Понял спасибо...
    Я использовал keybd_event вот таким образом:

    invoke keybd_event,VK_SNAPSHOT,0,0,0

    Был бы признателен, еслиб привели маленький пример по SendInput
     
  9. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    hakeem
    вечером из дома выложу, счас под рукой ничего нет.
     
  10. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    И еще если можно объясните, как сохранить содержимое буфера обмена куда нибудь?
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    hakeem
    Поиск по МСДН даст подробные ответы на все подобные вопросы,
    но он сильно жрёт трафик, так что гораздо лучше скачать или заказать MSDN или PSDK и иметь их всегда под рукой.
    ЗЫ: А одиночные примеры мало что проясняют - гораздо лучше подробное описание всех возможностей и нюансов применения функций.
     
  12. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    вот еще пример с клавой
    Код (Text):
    1. INPUT inp[4];
    2. memset(inp,0,sizeof(inp));
    3. inp[0].type=INPUT_KEYBOARD;
    4. inp[0].ki.wVk=VK_CONTROL;
    5. inp[1].type=INPUT_KEYBOARD;
    6. inp[1].ki.wVk='V';
    7. inp[2].type=INPUT_KEYBOARD;
    8. inp[2].ki.wVk='V';
    9. inp[2].ki.dwFlags=KEYEVENTF_KEYUP;
    10. inp[3].type=INPUT_KEYBOARD;
    11. inp[3].ki.wVk=VK_CONTROL;
    12. inp[3].ki.dwFlags=KEYEVENTF_KEYUP;
    13. SendInput(4,inp,sizeof(INPUT));
     
  13. KondraT

    KondraT Member

    Публикаций:
    0
    Регистрация:
    22 янв 2006
    Сообщения:
    175
    Код (Text):
    1. ; пишем в буфер обмена
    2. invoke GlobalAlloc, GMEM_FIXED, szData
    3. invoke OpenClipboard, hWin
    4. invoke EmptyClipboard
    5. invoke SetClipboardData, CF_TEXT, addr sData
    6. invoke CloseClipboard
    7.  
    8. ; читаем из буфера
    9. invoke OpenClipboard, hWin
    10. invoke GetClipboardData, CF_TEXT
    11. ; в eax - указатель на буфер с данными
     
  14. hakeem

    hakeem New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2008
    Сообщения:
    74
    KondraT , братан ты остановился на самом главном

    но как его сохранить?

    я симитировал нажатие кнопки print screen:

    Код (Text):
    1. start:
    2.  invoke keybd_event,VK_SNAPSHOT,0,0,0
    3.  invoke ExitProcess, 0
    4. end start
    в буфере содержится bitmap, я делаю так:

    Код (Text):
    1. ; читаем из буфера
    2. invoke OpenClipboard, hWin
    3. invoke GetClipboardData, CF_BITMAP
    4. ; в eax - указатель на буфер с данными
    ну а дальше, я в темном лесу , мне нужно либ сохранить картинку , либ показать её...
     
  15. Subrealist

    Subrealist Member

    Публикаций:
    0
    Регистрация:
    17 июл 2006
    Сообщения:
    134
    hakeem
    Я извиняюсь, вопрос не ко мне, но о том, как работать с битмапами, включая сохранение, есть примеры не только в мсдн, который может действительно трудно скачать и с онлайн версией которой по началу трудно разобраться, но и в короткой справке по винапи, около 4 м:
    http://cracklab.ru/download.php?action=get&n=NjA1
    Вот несколько переработанный код из этого справочника, предназначенный для сохранения в бмп любого окна, если с ним разобраться, подобным образом можно сохранить и из буфера обмена, вышеуказанный справочник тебе в этом поможет
    Код (Text):
    1. void SaveScreen(HWND hWnd)
    2. {
    3.     HDC hDC, CompDC;
    4.     SYSTEMTIME SysTm;
    5.     BITMAP bmp;
    6.     PBITMAPINFO pbmi;
    7.     HBITMAP hBitmap;
    8.     BITMAPFILEHEADER BFHeader;
    9.     WORD ClrBits;
    10.     DWORD dwTmp;
    11.     LPBYTE lpBits;
    12.     HANDLE hFile;
    13.     char FileName[22], dir[MAX_PATH];
    14.  
    15.     hDC=GetDC(hWnd);
    16.    
    17.     CompDC=CreateCompatibleDC(hDC);
    18.     hBitmap=CreateCompatibleBitmap(hDC, XSize, YSize);
    19.     SelectObject(CompDC,hBitmap);
    20.     BitBlt(CompDC,0,0,XSize,YSize,hDC,0,0,SRCCOPY);
    21.     ReleaseDC(hWnd, hDC);
    22.     GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bmp);
    23.     ClrBits=(WORD)bmp.bmPlanes*bmp.bmBitsPixel;
    24.     strcpy(dir,ScreenSaveDir);
    25.     if(ClrBits<=16)
    26.     {
    27.         ClrBits=16;
    28.     }
    29.     else
    30.     {
    31.         if(ClrBits<=24)
    32.         {
    33.             ClrBits=24;
    34.         }
    35.         else
    36.         {
    37.             ClrBits=32;
    38.         }
    39.     }
    40.    
    41.         pbmi=(PBITMAPINFO)new BYTE [sizeof(BITMAPINFOHEADER)];
    42.    
    43.     pbmi->bmiHeader.biClrUsed=0;
    44.     pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    45.     pbmi->bmiHeader.biWidth=bmp.bmWidth;
    46.     pbmi->bmiHeader.biHeight=bmp.bmHeight;
    47.     pbmi->bmiHeader.biPlanes=bmp.bmPlanes;
    48.     pbmi->bmiHeader.biBitCount=bmp.bmBitsPixel;
    49.     if(ClrBits<24)
    50.     {
    51.         pbmi->bmiHeader.biClrUsed=2^ClrBits;
    52.     }
    53.     pbmi->bmiHeader.biCompression=BI_RGB;
    54.     pbmi->bmiHeader.biSizeImage=(pbmi->bmiHeader.biWidth)*pbmi->bmiHeader.biHeight*(ClrBits/8);
    55.     pbmi->bmiHeader.biClrImportant=0;
    56.     lpBits= (UCHAR*)VirtualAlloc(NULL, pbmi->bmiHeader.biSizeImage, MEM_TOP_DOWN | MEM_COMMIT, PAGE_READWRITE);
    57.     GetDIBits(CompDC, hBitmap,0,pbmi->bmiHeader.biHeight,lpBits,pbmi,DIB_RGB_COLORS);
    58.     GetLocalTime(&SysTm);
    59.     sprintf(FileName,"\\%hu%02hu%02hu%02hu%02hu%02hu%03hu.bmp", SysTm.wYear,SysTm.wMonth,SysTm.wDay,SysTm.wHour,SysTm.wMinute,SysTm.wSecond,SysTm.wMilliseconds);
    60.     strcat(dir,FileName);
    61.     hFile=CreateFile(dir,GENERIC_READ|GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
    62.     BFHeader.bfType=0x4d42;
    63.     BFHeader.bfSize=sizeof(BITMAPFILEHEADER)+pbmi->bmiHeader.biSize+pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD)+pbmi->bmiHeader.biSizeImage;
    64.     BFHeader.bfReserved1=0;
    65.     BFHeader.bfReserved2=0;
    66.     BFHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+pbmi->bmiHeader.biSize+pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD);
    67.     WriteFile(hFile, &BFHeader, sizeof(BITMAPFILEHEADER),(LPDWORD)&dwTmp,0);
    68.     WriteFile(hFile, pbmi,sizeof(BITMAPINFOHEADER)+pbmi->bmiHeader.biClrUsed*sizeof(RGBQUAD),(LPDWORD)&dwTmp,0);
    69.     WriteFile(hFile,lpBits,pbmi->bmiHeader.biSizeImage,&dwTmp,0);
    70.     CloseHandle(hFile);
    71.  
    72.     DeleteDC(CompDC);
    73.     DeleteObject(hBitmap);
    74.     VirtualFree(lpBits, 0, MEM_RELEASE) ;
    75.     delete pbmi;
    76. }