一. 实验目的及内容
1.实验目的:理解Windows应用程序对键盘的响应。
2.实验内容:演示键盘输入时所产生的消息序列,并在窗口的客户区显示对应的字符
二.程序流程图请联系站长QQ752018766
三.所用仪器,材料
PC机一台
四. 程序代码
#include<windows.h>
#include<stdlib.h>
#include<string.h>
#include<iostream.h>
#define BufSize 50
void WINAPI CaretPos(int *xCaret,int *yCaret);
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)
{
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(&xCaret,&yCaret);
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(&xCaret,&yCaret);
InvalidateRect(hWnd,NULL,TRUE);
}
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(&xCaret,&yCaret);
ShowCaret(hWnd); //在活动焦点的窗口中显示插字符
}
break;
case WM_KILLFOCUS: //处理失去焦点消息
DestroyCaret();
break;
case WM_KEYDOWN: //处理按下键消息
{
switch(wParam)
{
case VK_END: //处理按下键为End时的消息
nArrayPos=nNumChar; //输入位置从本行的末尾开始
CaretPos(&xCaret,&yCaret);
break;
case VK_HOME: //处理按下键为Home时的消息
nArrayPos=0; //输入位置为本行的起始位置
CaretPos(&xCaret,&yCaret);
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];
nNumChar=nNumChar-1;
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case VK_LEFT:
if(nArrayPos>0)
{ nArrayPos=nArrayPos-1;
CaretPos(&xCaret,&yCaret);
}
else
MessageBox(hWnd,"您已经移动到起始位置,不能再往左移动了",NULL,MB_OK);
break;
case VK_RIGHT:
if(nArrayPos<nNumChar)
{ nArrayPos=nArrayPos+1; CaretPos(&xCaret,&yCaret); }
else
MessageBox(hWnd,"已经到缓冲区的末尾,不能再向右移动了",NULL,MB_OK);
break;
}
}
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)) ;
}
return 0;
}
void WINAPI CaretPos(int *xCaret,int *yCaret)
{ SetCaretPos(*xCaret,*yCaret); }
BOOL InitWindows(HINSTANCE hInstance,int nCmdShow)
{ HWND hWnd;
hWnd=CreateWindow("WinFill",
"祁宁的window",
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;
}
BOOL InitWindowsClass(HINSTANCE hInstance)
{
WNDCLASS WndClass;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(BLACK_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);
}