2016-03-08 3 views
1

Я пытаюсь создать простую программу, которую я могу использовать для упаковки программного обеспечения консоли. У меня есть основное окно с компонентом EDIT. Я знаю, что могу использовать WM_KEYUP и другие, чтобы перехватить вход keyborad. Я не могу найти эффективный способ преобразования любого из параметров CALLBACK WinProc; после чего я смогу завершить эту часть моей программы:Win32 - Как перехватить и обработать ввод в клавиатуру?

#include <windows.h> 

#define IDC_MAIN_EDIT 101 
#define WIDTH 800 
#define HEIGHT 600 

LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam); 

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd) { 
    WNDCLASSEX wClass; 
    ZeroMemory(&wClass,sizeof(WNDCLASSEX)); 
    wClass.cbSize=sizeof(WNDCLASSEX); 
    wClass.hbrBackground=(HBRUSH)COLOR_WINDOW; 
    wClass.hCursor=LoadCursor(NULL,IDC_ARROW); 
    wClass.hIcon=NULL; 
    wClass.hIconSm=NULL; 
    wClass.hInstance=hInst; 
    wClass.lpfnWndProc=(WNDPROC)WinProc; 
    wClass.lpszClassName="Window Class"; 
    wClass.lpszMenuName=NULL; 
    wClass.style=CS_HREDRAW|CS_VREDRAW; 

    if(!RegisterClassEx(&wClass)) { 
     int nResult=GetLastError(); 
     MessageBox(NULL, 
      "Window class creation failed", 
      "Window Class Failed", 
      MB_ICONERROR); 
    } 
    HWND hWnd=CreateWindowEx(0, 
      "Window Class", 
      "Windows application", 
      WS_OVERLAPPEDWINDOW, 
      200, 
      200, 
      640, 
      480, 
      NULL, 
      NULL, 
      hInst, 
      NULL); 

    if(!hWnd) { 
     int nResult=GetLastError(); 

     MessageBox(NULL, 
      "Window creation failed", 
      "Window Creation Failed", 
      MB_ICONERROR); 
    } 

    ShowWindow(hWnd,nShowCmd); 

    MSG msg; 
    ZeroMemory(&msg,sizeof(MSG)); 

    while(GetMessage(&msg,NULL,0,0)) { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
    return 0; 
} 

LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { 
    static HWND hEdit; 
    switch(msg) { 
     case WM_DESTROY: 
      PostQuitMessage(0); 
      return 0; 
      break; 
     case WM_CREATE: 
      hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, 
       "EDIT", 
       "", 
       WS_CHILD|WS_VISIBLE|ES_MULTILINE|WS_VISIBLE|WS_VSCROLL|ES_MULTILINE, 
       0, 
       0, 
       WIDTH, 
       HEIGHT, 
       hWnd, 
       (HMENU)IDC_MAIN_EDIT, 
       GetModuleHandle(NULL), 
       NULL); 
      HFONT hFont = CreateFont(0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Courier New")); 
      SendMessage(hEdit, WM_SETFONT, (WPARAM)hFont, 0); 
      SendMessage(hEdit, 
       WM_SETTEXT, 
       0, 
       (LPARAM)"Insert text here..."); 
       break; 
     case WM_SIZE: 
      MoveWindow(hEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); 
      break; 
    } 
    return DefWindowProc(hWnd,msg,wParam,lParam); 
} 

То, что я должен был сказать: Я не могу найти способ перехвата ввода с клавиатуры в качестве символов. Как я могу перехватить весь обычный ввод с клавиатуры?

+0

Что значит «я не может показаться эффективным средством для преобразования любого из параметров CALLBACK WinProc? Ваша проблема неясна. –

+0

@JonathanPotter Извините, это лучше? – motoku

+0

Когда пользователь вводит элемент управления редактирования, родительское окно будет получать уведомления «EN_CHANGE» в виде сообщений «WM_COMMAND» - это то, что вы ищете? –

ответ

2

Чтобы ответить на ваш вопрос:

То, что я должен был сказать: Я не могу показаться, чтобы найти путь к перехвата ввода с клавиатуры в качестве символов. Как я могу перехватить весь обычный ввод клавиатуры ?

Взгляните на этот пример от Microsoft о том, как обработать сообщение WM_CHAR, чтобы получить ввод клавиатуры символов:

Использование Ввод с клавиатуры

https://msdn.microsoft.com/en-us/library/windows/desktop/ms646268(v=vs.85).aspx

#define BUFSIZE 65535 
#define SHIFTED 0x8000 

LONG APIENTRY MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    HDC hdc;     // handle to device context 
    TEXTMETRIC tm;    // structure for text metrics 
    static DWORD dwCharX;  // average width of characters 
    static DWORD dwCharY;  // height of characters 
    static DWORD dwClientX; // width of client area 
    static DWORD dwClientY; // height of client area 
    static DWORD dwLineLen; // line length 
    static DWORD dwLines;  // text lines in client area 
    static int nCaretPosX = 0; // horizontal position of caret 
    static int nCaretPosY = 0; // vertical position of caret 
    static int nCharWidth = 0; // width of a character 
    static int cch = 0;  // characters in buffer 
    static int nCurChar = 0; // index of current character 
    static PTCHAR pchInputBuf; // input buffer 
    int i, j;     // loop counters 
    int cCR = 0;    // count of carriage returns 
    int nCRIndex = 0;   // index of last carriage return 
    int nVirtKey;    // virtual-key code 
    TCHAR szBuf[128];   // temporary buffer 
    TCHAR ch;     // current character 
    PAINTSTRUCT ps;   // required by BeginPaint 
    RECT rc;     // output rectangle for DrawText 
    SIZE sz;     // string dimensions 
    COLORREF crPrevText;  // previous text color 
    COLORREF crPrevBk;   // previous background color 
    size_t * pcch; 
    HRESULT hResult; 

    switch (uMsg) 
    { 
     case WM_CREATE: 

      // Get the metrics of the current font. 

      hdc = GetDC(hwndMain); 
      GetTextMetrics(hdc, &tm); 
      ReleaseDC(hwndMain, hdc); 

      // Save the average character width and height. 

      dwCharX = tm.tmAveCharWidth; 
      dwCharY = tm.tmHeight; 

      // Allocate a buffer to store keyboard input. 

      pchInputBuf = (LPTSTR) GlobalAlloc(GPTR, 
       BUFSIZE * sizeof(TCHAR)); 
      return 0; 

     case WM_SIZE: 

      // Save the new width and height of the client area. 

      dwClientX = LOWORD(lParam); 
      dwClientY = HIWORD(lParam); 

      // Calculate the maximum width of a line and the 
      // maximum number of lines in the client area. 

      dwLineLen = dwClientX - dwCharX; 
      dwLines = dwClientY/dwCharY; 
      break; 


     case WM_SETFOCUS: 

      // Create, position, and display the caret when the 
      // window receives the keyboard focus. 

      CreateCaret(hwndMain, (HBITMAP) 1, 0, dwCharY); 
      SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); 
      ShowCaret(hwndMain); 
      break; 

     case WM_KILLFOCUS: 

      // Hide and destroy the caret when the window loses the 
      // keyboard focus. 

      HideCaret(hwndMain); 
      DestroyCaret(); 
      break; 

     case WM_CHAR: 
     // check if current location is close enough to the 
     // end of the buffer that a buffer overflow may 
     // occur. If so, add null and display contents. 
    if (cch > BUFSIZE-5) 
    { 
     pchInputBuf[cch] = 0x00; 
     SendMessage(hwndMain, WM_PAINT, 0, 0); 
    } 
      switch (wParam) 
      { 
       case 0x08: // backspace 
       case 0x0A: // linefeed 
       case 0x1B: // escape 
        MessageBeep((UINT) -1); 
        return 0; 

       case 0x09: // tab 

        // Convert tabs to four consecutive spaces. 

        for (i = 0; i < 4; i++) 
         SendMessage(hwndMain, WM_CHAR, 0x20, 0); 
        return 0; 

       case 0x0D: // carriage return 

        // Record the carriage return and position the 
        // caret at the beginning of the new line. 

        pchInputBuf[cch++] = 0x0D; 
        nCaretPosX = 0; 
        nCaretPosY += 1; 
        break; 

       default: // displayable character 

        ch = (TCHAR) wParam; 
        HideCaret(hwndMain); 

        // Retrieve the character's width and output 
        // the character. 

        hdc = GetDC(hwndMain); 
        GetCharWidth32(hdc, (UINT) wParam, (UINT) wParam, 
         &nCharWidth); 
        TextOut(hdc, nCaretPosX, nCaretPosY * dwCharY, 
         &ch, 1); 
        ReleaseDC(hwndMain, hdc); 

        // Store the character in the buffer. 

        pchInputBuf[cch++] = ch; 

        // Calculate the new horizontal position of the 
        // caret. If the position exceeds the maximum, 
        // insert a carriage return and move the caret 
        // to the beginning of the next line. 

        nCaretPosX += nCharWidth; 
        if ((DWORD) nCaretPosX > dwLineLen) 
        { 
         nCaretPosX = 0; 
         pchInputBuf[cch++] = 0x0D; 
         ++nCaretPosY; 
        } 
        nCurChar = cch; 
        ShowCaret(hwndMain); 
        break; 
      } 
      SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); 
      break; 

     case WM_KEYDOWN: 
      switch (wParam) 
      { 
       case VK_LEFT: // LEFT ARROW 

        // The caret can move only to the beginning of 
        // the current line. 

        if (nCaretPosX > 0) 
        { 
         HideCaret(hwndMain); 

         // Retrieve the character to the left of 
         // the caret, calculate the character's 
         // width, then subtract the width from the 
         // current horizontal position of the caret 
         // to obtain the new position. 

         ch = pchInputBuf[--nCurChar]; 
         hdc = GetDC(hwndMain); 
         GetCharWidth32(hdc, ch, ch, &nCharWidth); 
         ReleaseDC(hwndMain, hdc); 
         nCaretPosX = max(nCaretPosX - nCharWidth, 
          0); 
         ShowCaret(hwndMain); 
        } 
        break; 

       case VK_RIGHT: // RIGHT ARROW 

        // Caret moves to the right or, when a carriage 
        // return is encountered, to the beginning of 
        // the next line. 

        if (nCurChar < cch) 
        { 
         HideCaret(hwndMain); 

         // Retrieve the character to the right of 
         // the caret. If it's a carriage return, 
         // position the caret at the beginning of 
         // the next line. 

         ch = pchInputBuf[nCurChar]; 
         if (ch == 0x0D) 
         { 
          nCaretPosX = 0; 
          nCaretPosY++; 
         } 

         // If the character isn't a carriage 
         // return, check to see whether the SHIFT 
         // key is down. If it is, invert the text 
         // colors and output the character. 

         else 
         { 
          hdc = GetDC(hwndMain); 
          nVirtKey = GetKeyState(VK_SHIFT); 
          if (nVirtKey & SHIFTED) 
          { 
           crPrevText = SetTextColor(hdc, 
            RGB(255, 255, 255)); 
           crPrevBk = SetBkColor(hdc, 
            RGB(0,0,0)); 
           TextOut(hdc, nCaretPosX, 
            nCaretPosY * dwCharY, 
            &ch, 1); 
           SetTextColor(hdc, crPrevText); 
           SetBkColor(hdc, crPrevBk); 
          } 

          // Get the width of the character and 
          // calculate the new horizontal 
          // position of the caret. 

          GetCharWidth32(hdc, ch, ch, &nCharWidth); 
          ReleaseDC(hwndMain, hdc); 
          nCaretPosX = nCaretPosX + nCharWidth; 
         } 
         nCurChar++; 
         ShowCaret(hwndMain); 
         break; 
        } 
        break; 

       case VK_UP:  // UP ARROW 
       case VK_DOWN: // DOWN ARROW 
        MessageBeep((UINT) -1); 
        return 0; 

       case VK_HOME: // HOME 

        // Set the caret's position to the upper left 
        // corner of the client area. 

        nCaretPosX = nCaretPosY = 0; 
        nCurChar = 0; 
        break; 

       case VK_END: // END 

        // Move the caret to the end of the text. 

        for (i=0; i < cch; i++) 
        { 
         // Count the carriage returns and save the 
         // index of the last one. 

         if (pchInputBuf[i] == 0x0D) 
         { 
          cCR++; 
          nCRIndex = i + 1; 
         } 
        } 
        nCaretPosY = cCR; 

        // Copy all text between the last carriage 
        // return and the end of the keyboard input 
        // buffer to a temporary buffer. 

        for (i = nCRIndex, j = 0; i < cch; i++, j++) 
         szBuf[j] = pchInputBuf[i]; 
        szBuf[j] = TEXT('\0'); 

        // Retrieve the text extent and use it 
        // to set the horizontal position of the 
        // caret. 

        hdc = GetDC(hwndMain); 
        hResult = StringCchLength(szBuf, 128, pcch); 
        if (FAILED(hResult)) 
        { 
        // TODO: write error handler 
        } 
        GetTextExtentPoint32(hdc, szBuf, *pcch, 
         &sz); 
        nCaretPosX = sz.cx; 
        ReleaseDC(hwndMain, hdc); 
        nCurChar = cch; 
        break; 

       default: 
        break; 
      } 
      SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); 
      break; 

     case WM_PAINT: 
      if (cch == 0)  // nothing in input buffer 
       break; 

      hdc = BeginPaint(hwndMain, &ps); 
      HideCaret(hwndMain); 

      // Set the clipping rectangle, and then draw the text 
      // into it. 

      SetRect(&rc, 0, 0, dwLineLen, dwClientY); 
      DrawText(hdc, pchInputBuf, -1, &rc, DT_LEFT); 

      ShowCaret(hwndMain); 
      EndPaint(hwndMain, &ps); 
      break; 

     // Process other messages. 

     case WM_DESTROY: 
      PostQuitMessage(0); 

      // Free the input buffer. 

      GlobalFree((HGLOBAL) pchInputBuf); 
      UnregisterHotKey(hwndMain, 0xAAAA); 
      break; 

     default: 
      return DefWindowProc(hwndMain, uMsg, wParam, lParam); 
    } 
    return NULL; 
} 
+0

Только для ссылок/только для кода ответов нет. Вам нужно объяснить, какова основная проблема и как это решение решает эту проблему. – IInspectable

+0

@Инспективный Я отредактировал ответ. – kvr

Смежные вопросы