#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))//消息循環(huán)
 {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}

//消息處理函數(shù)
long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)
  {
#define BufSize 30 //設(shè)置存放字符的緩沖區(qū)大小
static char cCharBuf[BufSize];//設(shè)置靜態(tài)字符數(shù)組,
static int nNumChar=0;//現(xiàn)有字符個數(shù)
static int nArrayPos=0;//字符的位置
static int nLnHeight;
static int nCharWidth;
static int xCaret,yCaret;
int x;
HDC hDC;
TEXTMETRIC tm;
PAINTSTRUCT PtStr; //定義指向包含繪圖信息的結(jié)構(gòu)體變量

switch(iMessage) //處理消息
 {
case WM_CHAR: //遇到非系統(tǒng)字符所作的處理
 {
if(wParam==VK_BACK) //處理退格鍵的消息
 {
if(nArrayPos==0) //若已在一行文字的開始處,則提示用戶"不能回退"
MessageBox(hWnd,"當(dāng)前位置是文本的起始位置,不能回退",NULL,MB_OK);
else
 {
nArrayPos=nArrayPos-1; //按一次回退鍵就回退一字符位置
CaretPos(hWnd,nArrayPos,cCharBuf,&xCaret, &yCaret,nCharWidth);
nNumChar=nNumChar-1; //對現(xiàn)有字符總數(shù)進(jìn)行計數(shù)
InvalidateRect(hWnd,NULL,TRUE);//刷新用戶區(qū)并發(fā)送WM_PAINT消息
}
break;
}

if(wParam<=VK_ESCAPE) //處理按下Escape鍵消息
 {
MessageBox(hWnd,"您現(xiàn)在不能按ESC鍵,請繼續(xù)其它操作",NULL,MB_OK);
break;
}

if(nNumChar>=BufSize) //如寫入的字符數(shù)超過緩沖區(qū)大小,則報警
 {
MessageBox(hWnd,"緩沖區(qū)已滿,不能再輸入字符了\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: //處理窗口創(chuàng)建消息
 {
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,"緩沖區(qū)已空,沒有字符可供刪除",NULL,MB_OK);
else
 {
for(x=nArrayPos;x<nNumChar;x=x+1)
cCharBuf[x]=cCharBuf[x+1]; //每刪一字符,緩沖區(qū)中總字符數(shù)減1
nNumChar=nNumChar-1;
InvalidateRect(hWnd,NULL,TRUE); //用戶區(qū)刷新
}
break;

case VK_LEFT: //處理按下左方向鍵時的消息
if(nArrayPos>0)
 {
nArrayPos=nArrayPos-1; //當(dāng)前輸入位置往前移一個位置,再輸入字符時,等于插入字符
CaretPos(hWnd,nArrayPos,cCharBuf,&xCaret,&yCaret,nCharWidth);
}
else //已經(jīng)移到起始輸入位置,不能再往前了
MessageBox(hWnd,"您已經(jīng)移動到起始位置,不能再往左移動了",NULL,MB_OK);
break;

case VK_RIGHT: // 處理按下右方向鍵時的消息
if(nArrayPos<nNumChar) // 如果當(dāng)前位置沒有到緩沖區(qū)的最后位置,還能向右移動
 {
nArrayPos=nArrayPos+1;
CaretPos(hWnd,nArrayPos,cCharBuf,&xCaret,&yCaret,nCharWidth);
}
else
MessageBox(hWnd,"已經(jīng)到緩沖區(qū)的末尾,不能再向右 移動了",NULL,MB_OK);
break;
}
}//end case WM_KEYDOWN
break;

case WM_PAINT: //處理重畫消息
  {
hDC=BeginPaint(hWnd,&PtStr);
TextOut(hDC,nCharWidth,nLnHeight,cCharBuf,nNumChar); //輸出緩沖區(qū)中的文本
EndPaint(hWnd,&PtStr);
}
break;

case WM_DESTROY: //處理結(jié)束應(yīng)用程序消息
PostQuitMessage(0);//結(jié)束應(yīng)用程序
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) //處理插字符位置的函數(shù)
  {
DWORD dWord;
HDC hDC; //定義設(shè)備描述表句柄
hDC=GetDC(hWnd); //取得當(dāng)前設(shè)備描述表句柄
ReleaseDC(hWnd,hDC);
*xCaret=LOWORD(dWord)+nCharWidth;
SetCaretPos(*xCaret,*yCaret); //設(shè)置插字符位置坐標(biāo)
}

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); //繪制用戶區(qū)
return TRUE;
}




|