处理键盘输入

【勇芳软件工作室】汉化HomePreviousNext

以下示例演示了如何在简单的文本编辑器中使用插入符号。该示例在用户键入可打印字符时更新插入符位置,并使用各种键移动通过客户端区域。

#define TEXTMATRIX(x,y)*(pTextMatrix +(y * nWindowCharsX)+ x)

//全局变量

HINSTANCE hinst; //当前实例

HBITMAP hCaret; //插入位图

HDC hdc; //设备上下文

PAINTSTRUCT ps; //客户区画面信息

static char *pTextMatrix = NULL; //指向文本矩阵

static int nCharX, // char的宽度。以逻辑单位

nCharY, // char的高度以逻辑单位

nWindowX, //客户区域的宽度

nWindowY, //客户区域的高度

nWindowCharsX, //客户区域的宽度

nWindowCharsY, //客户区域的高度

nCaretPosX, //插入符的x位置

nCaretPosY; //插入符的y位置

static UINT uOldBlink; //以前的眨眼速率

int x, y; //用于文本矩阵中的x和y坐标

TEXTMETRIC tm; //字体信息

龙APIENTRY MainWndProc(

HWND hwnd, //窗口句柄

UINT message, //消息类型

UINT wParam, // 附加信息

LONG lParam) // 附加信息

{

开关(讯息)

{

case WM_CREATE:

//选择固定宽度的系统字体,并获取其文本度量。

hdc = GetDC(hwnd);

SelectObject(hdc,

GetStockObject(SYSTEM_FIXED_FONT));

GetTextMetrics(hdc, &tm);

ReleaseDC(hwnd, hdc);

//保存平均字符的宽度和高度。

nCharX = tm.tmAveCharWidth;

nCharY = tm.tmHeight;

return 0;

case WM_SIZE:

//确定客户区域的宽度,以像素为单位

//和字符数。

nWindowX = LOWORD(lParam);

nWindowCharsX = max(1, nWindowX/nCharX);

//确定客户区域的高度

//像素和字符数。

nWindowY = HIWORD(lParam);

nWindowCharsY = max(1, nWindowY/nCharY);

//清除保存文本输入的缓冲区。

if (pTextMatrix != NULL)

free(pTextMatrix);

//如果有足够的内存,请为此分配空间

//文本输入缓冲区。

pTextMatrix = malloc(nWindowCharsX * nWindowCharsY);

if (pTextMatrix == NULL)

ErrorHandler("Not enough memory.");

其他

for (y = 0; y < nWindowCharsY; y++)

for (x = 0; x < nWindowCharsX; x++)

TEXTMATRIX(x, y) = ' ';

//将插入符号移动到原点。

SetCaretPos(0, 0);

return 0;

case WM_KEYDOWN:

开关(wParam)

{

case VK_HOME: //首页

nCaretPosX = 0;

break;

case VK_END: // 结束

nCaretPosX = nWindowCharsX - 1;

break;

case VK_PRIOR: //向上翻页

nCaretPosY = 0;

break;

case VK_NEXT: // 向下翻页

nCaretPosY = nWindowCharsY -1;

break;

case VK_LEFT: // 左箭头

nCaretPosX = max(nCaretPosX - 1, 0);

break;

case VK_RIGHT: // 右箭头

nCaretPosX = min(nCaretPosX + 1,

nWindowCharsX - 1);

break;

case VK_UP: // 向上箭头

nCaretPosY = max(nCaretPosY - 1, 0);

break;

case VK_DOWN: //向下箭头

nCaretPosY = min(nCaretPosY + 1,

nWindowCharsY - 1);

break;

case VK_DELETE: //删除

//移动后面的所有字符

//删除的字符(在同一行)一个

//空格返回(向左)矩阵。

for (x = nCaretPosX; x < nWindowCharsX; x++)

TEXTMATRIX(x, nCaretPosY) =

TEXTMATRIX(x + 1, nCaretPosY);

//替换最后一个字符

//有一个空格。

TEXTMATRIX(nWindowCharsX - 1,

nCaretPosY) = ' ';

//应用程序将在外面绘制

// WM_PAINT消息处理,所以隐藏插入符号。

HideCaret(hwnd);

//重绘行,调整为

//已删除的字符。

hdc = GetDC(hwnd);

SelectObject(hdc,

GetStockObject(SYSTEM_FIXED_FONT));

TextOut(hdc,nCaretPosX * nCharX,

nCaretPosY陈,

& TEXTMATRIX(nCaretPosX,nCaretPosY),

nWindowCharsX - nCaretPosX);

ReleaseDC(hwnd, hdc);

//显示插入符号。

ShowCaret(hwnd);

break;

}

//调整插入符号位置

//虚拟键处理。

SetCaretPos(nCaretPosX * nCharX,

nCaretPosY * nCharY);

return 0;

case WM_CHAR:

开关(wParam)

{

case 0x08: //退格

//将插入符号移回一个空格,然后

//处理这个像DEL键。

if(nCaretPosX > 0)

{

nCaretPosX--;

sendMessage(hwnd,WM_KEYDOWN,

VK_DELETE, 1L);

}

break;

case 0x09: // 标签

// Tab停止每四个空格存在,所以添加

//空格,直到用户点击下一个选项卡。

do

{

SendMessage(hwnd, WM_CHAR, ' ', 1L);

} while (nCaretPosX % 4 != 0);

break;

case 0x0D: //回车返回

//转到下一行的开始。

//底线包裹在顶部。

nCaretPosX = 0;

if (++nCaretPosY == nWindowCharsY)

nCaretPosY = 0;

break;

case 0x1B: //逃脱

case 0x0A: //换行

MessageBeep((UINT) -1);

break;

默认:

//将字符添加到文本缓冲区。

TEXTMATRIX(nCaretPosX, nCaretPosY) =

(char) wParam;

//应用程序将在外面绘制

// WM_PAINT消息处理,所以隐藏插入符号。

HideCaret(hwnd);

//在屏幕上绘制字符

hdc = GetDC(hwnd);

SelectObject(hdc,

GetStockObject(SYSTEM_FIXED_FONT));

TextOut(hdc,nCaretPosX * nCharX,

nCaretPosY陈,

&TEXTMATRIX(nCaretPosX, nCaretPosY), 1);

ReleaseDC(hwnd, hdc);

//显示插入符号。

ShowCaret(hwnd);

//如果你到达,准备回来

// 队伍的尽头。

if (++nCaretPosX == nWindowCharsX)

{

nCaretPosX = 0;

if (++nCaretPosY == nWindowCharsY)

nCaretPosY = 0;

}

break;

}

//调整插入符号位置

//字符处理。

SetCaretPos(nCaretPosX * nCharX,

nCaretPosY * nCharY);

return 0;

case WM_PAINT:

//逐行绘制缓冲区中的所有字符。

hdc = BeginPaint(hwnd, &ps);

SelectObject(hdc,

GetStockObject(SYSTEM_FIXED_FONT));

for (y = 0; y < nWindowCharsY; y++)

TextOut(hdc,0,y * nCharY,& TEXTMATRIX(0,y),

nWindowCharsX);

EndPaint(hwnd, &ps);

case WM_SETFOCUS:

//窗口有输入焦点。加载

//应用程序定义的插入符资源。

hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));

//创建插入符号。

CreateCaret(hwnd, hCaret, 0, 0);

//调整插入位置。

SetCaretPos(nCaretPosX * nCharX,

nCaretPosY * nCharY);

//显示插入符号。

ShowCaret(hwnd);

break;

case WM_KILLFOCUS:

//窗口正在丢失输入焦点,

//所以摧毁插入符号。

DestroyCaret();

break;

默认:

return DefWindowProc(hwnd, message, wParam, lParam);

}

return NULL;

}