windows 键盘

#include <windows.h>  
 
#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)  
 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;  
 
//建立窗口框架  
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,  
                    PSTR szCmdLine, int iCmdShow)  
{  
     static TCHAR szAppName[] = TEXT ("Typer") ;  
     HWND         hwnd ;  
     MSG          msg ;  
     WNDCLASS     wndclass ;  
       
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;  
     wndclass.lpfnWndProc   = WndProc ;  
     wndclass.cbClsExtra    = 0 ;  
     wndclass.cbWndExtra    = 0 ;  
     wndclass.hInstance     = hInstance ;  
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;  
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;  
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;  
     wndclass.lpszMenuName  = NULL ;  
     wndclass.lpszClassName = szAppName ;  
       
     if (!RegisterClass (&wndclass))  
     {  
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),   
                      szAppName, MB_ICONERROR) ;  
          return 0 ;  
     }  
       
     hwnd = CreateWindow (szAppName, TEXT ("Typing Program"),  
                          WS_OVERLAPPEDWINDOW,  
                          CW_USEDEFAULT, CW_USEDEFAULT,  
                          CW_USEDEFAULT, CW_USEDEFAULT,  
                          NULL, NULL, hInstance, NULL) ;  
       
     ShowWindow (hwnd, iCmdShow) ;  
     UpdateWindow (hwnd) ;  
       
     while (GetMessage (&msg, NULL, 0, 0))  
     {  
          TranslateMessage (&msg) ;  
          DispatchMessage (&msg) ;  
     }  
     return msg.wParam ;  
}  
 
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
{  
     static DWORD   dwCharSet = DEFAULT_CHARSET ;  
     static int     cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,  
                    xCaret, yCaret ;  
     static TCHAR * pBuffer = NULL ;  
     HDC            hdc ;  
     int            x, y, i ;  
     PAINTSTRUCT    ps ;  
     TEXTMETRIC     tm ;  
       
     switch (message)  
     {  
     case WM_INPUTLANGCHANGE: //输入法发生变化,修改字符集  
          dwCharSet = wParam ;  
          // fall through  
     case WM_CREATE: //窗体创建  
          hdc = GetDC (hwnd) ;  
          //创建缺省字体,并设置为默认字体  
          SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,  
                                   dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;  
          //获取字体大小  
          GetTextMetrics (hdc, &tm) ;  
          cxChar = tm.tmAveCharWidth ;  
          cyChar = tm.tmHeight ;  
          //删除刚创建的缺省字体,并选入系统字体  
          DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;  
          ReleaseDC (hwnd, hdc) ;  
          // fall through                  
     case WM_SIZE:  
          //窗体大小重设  
          if (message == WM_SIZE)  
          {  
               cxClient = LOWORD (lParam) ;  
               cyClient = HIWORD (lParam) ;  
          }  
          //计算需要多大的内存来容纳字符串  
          cxBuffer = max (1, cxClient / cxChar) ;  
          cyBuffer = max (1, cyClient / cyChar) ;  
            
          //释放之前的内存  
          if (pBuffer != NULL)  
               free (pBuffer) ;  
          //重新申请一块内存  
          pBuffer = (TCHAR *) malloc (cxBuffer * cyBuffer * sizeof (TCHAR)) ;  
          //并置为空字符串  
          for (y=0; y<cyBuffer; y++){  
              for (x=0; x<cxBuffer; x++){  
                  BUFFER(x,y) = ' ' ;
              }
          }
                      
          //设置插入符号的位置为0,0  
          xCaret = 0 ;  
          yCaret = 0 ;  
          //若为焦点窗口则重新设置插入符号位置  
          if (hwnd == GetFocus ())  
               SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;  
 
          InvalidateRect (hwnd, NULL, TRUE) ;  
          return 0 ;  
                      
     case WM_SETFOCUS:  
          // 获得焦点时创建并设置输入光标位置  
          CreateCaret (hwnd, NULL, cxChar, cyChar);  
          SetCaretPos (xCaret * cxChar, yCaret * cyChar);  
          ShowCaret (hwnd);  
          return 0 ;  
            
     case WM_KILLFOCUS:  
          // 失去焦点时隐藏并销毁插入符号  
          HideCaret (hwnd) ;  
          DestroyCaret () ;  
          return 0 ;  
            
     case WM_KEYDOWN: //通过按键消息控制插入符位置,VK_DELETE删除字符  
          switch (wParam)  
          {  
          case VK_HOME:  
               xCaret = 0 ;  
               break;  
                 
          case VK_END:  
               xCaret = cxBuffer - 1;
               break;
                 
          case VK_PRIOR:  
               yCaret = 0 ;  
               break;  
                 
          case VK_NEXT:  
               yCaret = cyBuffer - 1 ;  
               break;  
                 
          case VK_LEFT:  
               xCaret = max (xCaret - 1, 0) ;  
               break;  
                 
          case VK_RIGHT:  
               xCaret = min (xCaret + 1, cxBuffer - 1) ;  
               break;  
                 
          case VK_UP:  
               yCaret = max (yCaret - 1, 0) ;  
               break;  
                 
          case VK_DOWN:  
               yCaret = min (yCaret + 1, cyBuffer - 1) ;  
               break;  
                 
          case VK_DELETE: //删除字符  
               //当前行所有在被删除字符之后的字符都向前移动一位  
               for (x = xCaret; x< cxBuffer - 1; x++)  
                    BUFFER (x, yCaret) = BUFFER (x + 1, yCaret) ;  
               //最后一位设置为空  
               BUFFER (cxBuffer - 1, yCaret) = ' ';  
               //隐藏光标  
               HideCaret (hwnd) ;  
               //获取DC  
               hdc = GetDC (hwnd) ;  
               //设置缺省字体  
               SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,  
                                   dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;  
               //输出文字  
               TextOut (hdc, xCaret * cxChar, yCaret * cyChar,  
                        & BUFFER (xCaret, yCaret),  
                        cxBuffer - xCaret) ;  
               //删除创建的缺省字体并选中默认字体  
               DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;  
               ReleaseDC (hwnd, hdc) ;  
               //重新显示光标  
               ShowCaret (hwnd) ;  
               break ;  
          }  
          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;  
          return 0 ;  
            
     case WM_CHAR: //处理字符消息  
          for (i=0 ; i<(int)LOWORD (lParam) ; i++)  
          {  
               switch (wParam)  
               {  
               case '\b':                    // backspace  
                    if (xCaret > 0)  
                    {  
                         xCaret-- ;  
                         SendMessage (hwnd, WM_KEYDOWN, VK_DELETE, 1) ;  
                    }  
                    break ;  
                      
               case '\t':                    // tab  
                    do  
                    {  
                         SendMessage (hwnd, WM_CHAR, ' ', 1) ;  
                    }  
                    while (xCaret % 8 != 0) ;  
                    break ;  
                      
               case '\n':                    // line feed  
                    if (++yCaret == cyBuffer)  
                         yCaret = 0 ;  
                    break ;  
                      
               case '\r':                    // carriage return  
                    xCaret = 0 ;  
                      
                    if (++yCaret == cyBuffer)  
                         yCaret = 0 ;  
                    break ;  
                      
               case '\x1B':                  // escape  
                    for (y = 0 ; y < cyBuffer ; y++)  
                         for (x = 0 ; x < cxBuffer ; x++)  
                              BUFFER (x, y) = ' ' ;  
                           
                    xCaret = 0 ;  
                    yCaret = 0 ;  
                           
                    InvalidateRect (hwnd, NULL, FALSE) ;  
                    break ;  
                           
               default:                      // character codes  
                    //在当前字符插入符号所在位置插入字符并显示,过程与VK_DELETE相似  
                    BUFFER (xCaret, yCaret) = (TCHAR) wParam ;  
                      
                    HideCaret (hwnd) ;  
                    hdc = GetDC (hwnd) ;  
            
                    SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,  
                                   dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;  
 
                    TextOut (hdc, xCaret * cxChar, yCaret * cyChar,  
                             & BUFFER (xCaret, yCaret), 1) ;  
 
                    DeleteObject (  
                         SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;  
                    ReleaseDC (hwnd, hdc) ;  
                    ShowCaret (hwnd) ;  
 
                    if (++xCaret == cxBuffer)  
                    {  
                         xCaret = 0 ;  
                           
                         if (++yCaret == cyBuffer)  
                              yCaret = 0 ;  
                    }  
                    break ;  
               }  
          }  
            
          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;  
          return 0 ;  
            
     case WM_PAINT:  
          hdc = BeginPaint (hwnd, &ps) ;  
          //选中字体  
          SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,  
                                   dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;  
          //画出所有字符串                      
          for (y = 0 ; y < cyBuffer ; y++){
              if(BUFFER(0,y)>=65&&BUFFER(0,y)<97){
                  TextOut (hdc, 0, y * cyChar, & BUFFER(0,y)+32, cxBuffer);
              }else if(BUFFER(0,y)>=97&&BUFFER(0,y)<=122){
                  TextOut (hdc, 0, y * cyChar, & BUFFER(0,y)-32, cxBuffer);
              }else{
                  TextOut (hdc, 0, y * cyChar, "no", lstrlen("no"));
              }
          }  
          //删除,并设置为默认字体  
          DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;  
          EndPaint (hwnd, &ps) ;  
          return 0 ;  
            
     case WM_DESTROY:  
          PostQuitMessage (0) ;  
          return 0 ;  
     }  
     return DefWindowProc (hwnd, message, wParam, lParam) ;  
}

猜你喜欢

转载自blog.csdn.net/sinat_38026845/article/details/80181880