#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;
}