#include<windows.h>
#include
<stdlib.h>
#include
<string.h>
void WINAPI CaretPos(HWND hWnd,    int nArrayPos,char *cCharBuf,int *xCaret,int *yCaret,int nCharWidth);
long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam);
BOOL InitWindowsClass(HINSTANCE hInstance);
BOOL InitWindows(HINSTANCE hInstance,
int nCmdShow);
HWND hWndMain;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

    MSG Message;
    
if(!InitWindowsClass(hInstance)) return FALSE;
    
if(!InitWindows(hInstance,nCmdShow))  return FALSE;
    
while(GetMessage(&Message,0,0,0))//消息循环
    {
        TranslateMessage(
&Message);
        DispatchMessage(
&Message);
    }

    
return Message.wParam;
}


//消息处理函数
long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)
{
  
#define BufSize 30    //设置存放字符的缓冲区大小
  
static char cCharBuf[BufSize];//设置静态字符数组,
  static int nNumChar=0;//现有字符个数
  static int nArrayPos=0;//字符的位置
  static int nLnHeight;
  
static int nCharWidth;
  
static int xCaret,yCaret;
  
int x;
  HDC hDC;
  TEXTMETRIC tm;
  PAINTSTRUCT PtStr; 
//定义指向包含绘图信息的结构体变量

  
switch(iMessage)      //处理消息
  {
   
case WM_CHAR:          //遇到非系统字符所作的处理
       {
         
if(wParam==VK_BACK)  //处理退格键的消息
         {
             
if(nArrayPos==0)     //若已在一行文字的开始处,则提示用户"不能回退"
               MessageBox(hWnd,"当前位置是文本的起始位置,不能回退",NULL,MB_OK);
            
else
            
{
               nArrayPos
=nArrayPos-1//按一次回退键就回退一字符位置
              CaretPos(hWnd,nArrayPos,cCharBuf,&xCaret,    &yCaret,nCharWidth);
              nNumChar
=nNumChar-1;    //对现有字符总数进行计数
              InvalidateRect(hWnd,NULL,TRUE);//刷新用户区并发送WM_PAINT消息  
            }
 
            
break
         }
 

         
if(wParam<=VK_ESCAPE) //处理按下Escape键消息
          {
           MessageBox(hWnd,
"您现在不能按ESC键,请继续其它操作",NULL,MB_OK);
              
break;
          }


        
if(nNumChar>=BufSize) //如写入的字符数超过缓冲区大小,则报警
         {
            MessageBox(hWnd,
"缓冲区已满,不能再输入字符了\n 若需要删除字符,请用BackSpace键",NULL,MB_OK);
            
break;
          }


        
for(x=nNumChar;x>nArrayPos;x=x-1)
              cCharBuf[x]
=cCharBuf[x-1];
            cCharBuf[nArrayPos]
=(unsigned char)wParam;
            nArrayPos
=nArrayPos+1;   
              nNumChar
=nNumChar+1;
            CaretPos(hWnd,nArrayPos,cCharBuf,
&xCaret,&yCaret,nCharWidth);
            InvalidateRect(hWnd,NULL,TRUE);
       }
//end case WM_CHAR:      
break;

case WM_CREATE: //处理窗口创建消息
       {    
             hDC
=GetDC(hWnd);
             GetTextMetrics(hDC,
&tm); //获取字体信息
            nLnHeight=tm.tmHeight+tm.tmExternalLeading;
             nCharWidth
=tm.tmAveCharWidth;
            yCaret
=nLnHeight;
            ReleaseDC(hWnd,hDC);
        }

            
break;

case WM_SETFOCUS: //处理活动焦点消息
    {
           CreateCaret(hWnd,
0,0,nLnHeight);
           CaretPos(hWnd,nArrayPos,cCharBuf,
&xCaret,&yCaret,nCharWidth);
           ShowCaret(hWnd); 
//在活动焦点的窗口中显示插字符
    }

break;

case WM_KILLFOCUS:         //处理失去焦点消息
                  DestroyCaret();
                  
break;

case WM_KEYDOWN: //处理按下键消息
{
    
switch(wParam)
    
{
         
case VK_END: //处理按下键为End时的消息
                   nArrayPos=nNumChar;//输入位置从本行的末尾开始
                   CaretPos(hWnd,nArrayPos,cCharBuf,&xCaret,&yCaret,nCharWidth);
                   
break;
         
case VK_HOME:    //处理按下键为Home时的消息
                    nArrayPos=0;    //输入位置为本行首位置
                  CaretPos(hWnd, nArrayPos,cCharBuf,    &xCaret,&yCaret,nCharWidth);
                  
break;
         
case VK_DELETE://处理按下键为Delete时的消息
                 if(nArrayPos==nNumChar)  //输入位置处于本行的末尾
                    MessageBox(hWnd,"缓冲区已空,没有字符可供删除",NULL,MB_OK);
                 
else
                 
{
                      
for(x=nArrayPos;x<nNumChar;x=x+1)
                        cCharBuf[x]
=cCharBuf[x+1]; //每删一字符,缓冲区中总字符数减1
                       nNumChar=nNumChar-1;
                       InvalidateRect(hWnd,NULL,TRUE); 
//用户区刷新
                 }

                 
break;

         
case VK_LEFT: //处理按下左方向键时的消息
                  if(nArrayPos>0)
                  
{
                      nArrayPos
=nArrayPos-1;  //当前输入位置往前移一个位置,再输入字符时,等于插入字符
                      CaretPos(hWnd,nArrayPos,cCharBuf,&xCaret,&yCaret,nCharWidth);
                  }

                  
else    //已经移到起始输入位置,不能再往前了
                    MessageBox(hWnd,"您已经移动到起始位置,不能再往左移动了",NULL,MB_OK);
                   
break

          
case VK_RIGHT:        // 处理按下右方向键时的消息
                if(nArrayPos<nNumChar)  // 如果当前位置没有到缓冲区的最后位置,还能向右移动
                 {
                  nArrayPos
=nArrayPos+1;
                  CaretPos(hWnd,nArrayPos,cCharBuf,
&xCaret,&yCaret,nCharWidth);
                }

                 
else
                   
                   MessageBox(hWnd,
"已经到缓冲区的末尾,不能再向右 移动了",NULL,MB_OK);
                  
break;
     }

}
//end case WM_KEYDOWN
 break;

case WM_PAINT: //处理重画消息
{
   hDC
=BeginPaint(hWnd,&PtStr);
   TextOut(hDC,nCharWidth,nLnHeight,cCharBuf,nNumChar);     
//输出缓冲区中的文本
   EndPaint(hWnd,&PtStr);
}

   
break;

case WM_DESTROY: //处理结束应用程序消息
    PostQuitMessage(0);//结束应用程序
    break;

default://其他消息处理程序
   return(DefWindowProc(hWnd,iMessage,wParam,lParam)) ;
}
//end 最外层switch

  
return 0;
}


void WINAPI CaretPos(HWND hWnd,    int nArrayPos,char *cCharBuf,int *xCaret,int *yCaret,int nCharWidth)    //处理插字符位置的函数
{
    DWORD dWord; 
    HDC hDC;            
//定义设备描述表句柄
    hDC=GetDC(hWnd);        //取得当前设备描述表句柄
    ReleaseDC(hWnd,hDC); 
    
*xCaret=LOWORD(dWord)+nCharWidth;
    SetCaretPos(
*xCaret,*yCaret);    //设置插字符位置坐标
}


BOOL InitWindowsClass(HINSTANCE hInstance)
//初始化窗口类
{
  WNDCLASS WndClass;
  WndClass.cbClsExtra
=0;
  WndClass.cbWndExtra
=0;
  WndClass.hbrBackground
=(HBRUSH)(GetStockObject(WHITE_BRUSH));
  WndClass.hCursor
=LoadCursor(NULL,IDC_ARROW);
  WndClass.hIcon
=LoadIcon(NULL,"END");
  WndClass.hInstance
=hInstance;
  WndClass.lpfnWndProc
=WndProc;
  WndClass.lpszClassName
="WinFill";
  WndClass.lpszMenuName
=NULL;
  WndClass.style
=CS_HREDRAW|CS_VREDRAW;
  
return RegisterClass(&WndClass);
}



BOOL InitWindows(HINSTANCE hInstance,
int nCmdShow)//初始化窗口
{    
  HWND hWnd;
  hWnd
=CreateWindow("WinFill",       //生成窗口
                 "填充示例程序",
                 WS_OVERLAPPEDWINDOW,
                 CW_USEDEFAULT,
                 
0,
                 CW_USEDEFAULT,
                 
0,
                 NULL,
                 NULL,
                 hInstance,
                 NULL);     
    
if(!hWnd)    return FALSE;
    hWndMain
=hWnd;
    ShowWindow(hWnd,nCmdShow);    
//显示窗口
    UpdateWindow(hWnd);        //绘制用户区
    return TRUE;
}