键盘输入程序中的退格功能

时间:2014-11-22 13:18:00

标签: c++ windows winapi keyboard

我正在学习win32编程,并为自己设置了一个简单的文本编辑程序作为第一项任务。

该程序主要基于此演示(在显示键盘输入部分下)

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268%28v=vs.85%29.aspx

我想修改此程序,因为它不处理退格键。我找到了这个代码(在处理键盘输入下):

http://msdn.microsoft.com/en-us/library/windows/desktop/ms648398%28v=vs.85%29.aspx

但是以不同的方式进行。它似乎是基于Petzold的书。此代码的问题是每次调整窗口大小时都会擦除当前输入。我想要一个允许输入,退格并且不擦除WM_SIZE上的文本的程序。

所以我想根据这个Petzold版本修改原始代码。

基本上我改变的是:

    switch (wParam) 
    { 
        case 0x08:  // backspace 
        case 0x0A:  // linefeed 

switch (wParam)
{
case 0x08:  // backspace 
    if (nCurChar > 0)
    {
        ch = pchInputBuf[--nCurChar];
        hdc = GetDC(hwnd);
        GetCharWidth32(hdc, ch, ch, &nCharWidth);
        ReleaseDC(hwnd, hdc);
        nCaretPosX = max(nCaretPosX - nCharWidth, 0);
        SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);
    }
    break;

并添加了一个VK_DELETE WM_KEYDOWN案例来执行此操作:

case VK_DELETE:
            for (int x = nCurChar; x < dwLineLen - 1; x++)
            {
                pchInputBuf[x] = pchInputBuf[x + 1];
            }

            HideCaret(hwnd);
            hdc = GetDC(hwnd);

            TextOut(hdc, nCaretPosX, nCaretPosY * dwCharY, &pchInputBuf[nCurChar], 1);

            DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));
            ReleaseDC(hwnd, hdc);
            ShowCaret(hwnd);
            break;

首次编译时似乎工作正常。退格键正确删除文本。但是我遇到了一些我不理解的故障。

首先,如果我键入以下内容:

input text

在一些退格后,插入符号和文本将不会返回正确的字符长度,如图所示(部分s仍然可见):

part of s showing

这有时只会发生,而不是所有时间。

其次,调整窗口大小有时会导致部分文本消失,而不是全部消失。通常是输入空格后的文本。但我需要编写几次程序才能实现这一目标。

有关最新情况的任何提示将不胜感激。感谢

1 个答案:

答案 0 :(得分:1)

我认为问题在于你的VK_DELETE处理程序中你没有正确地重新绘制显示。我每次都可以通过将光标移动到我输入的文本的中间然后按 Delete 键来解决它。代码似乎假设只删除了行中的最后一个字符,但情况并非总是这样。

尝试将其更改为:

            case VK_DELETE:
                    for (int x = nCurChar; x < dwLineLen - 1; x++)
                    {
                            pchInputBuf[x] = pchInputBuf[x + 1];
                    }
                    InvalidateRect(hwnd, 0, TRUE);
                    break;

这将让显示器完全被你的WM_PAINT处理程序重新绘制,至少对我而言似乎可以使它工作正常(在单行上 - 一旦文本换行到两行你有其他问题)。

如果您确认这可以解决问题,那么您可以坚持使用此解决方案,或者重新设计VK_DELETE处理程序以正确清除已删除的文本并重新绘制该行。