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

问题描述:

我正在学习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_DELETEWM_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

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

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

关于发生什么事情的任何提示将不胜感激。谢谢

+2

'DeleteObject(SelectObject(hdc,GetStockObject(SYSTEM_FONT)));'看起来错了,或者至少是不必要的。调用DC时什么字体被选入DC,何时被选中? – 2014-11-22 13:57:12

+0

你是对的,那是我尝试的东西遗留下来的。删除后仍然存在相同的问题。谢谢 – 2014-11-22 13:59:54

+0

你可以将整个项目发布在某个地方吗?从目前为止所显示的代码片段中,我看不到其他任何明显错误。但它被描述为间歇性的方式使我感到这是某种资源泄漏。 – 2014-11-22 14:01:35

我认为问题是,在您的VK_DELETE处理程序中,您不会正确重新绘制显示。我可以通过将光标移动到我输入的文本中间,然后按删除键来使它每次出错。代码似乎假设只有行中的最后一个字符被擦除,但情况并非总是如此。

尝试将其更改为这样:

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

这将让显示被你WM_PAINT处理器完全重新粉刷,并至少对我来说,这似乎使其工作正常(在一行那就是 - 只要文字包装成两行,就有其他问题)。

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

+0

谢谢。你是对的。我需要'InvalidateRect'。我发现的另一个问题是我在混合'TextOut'和'DrawText'。我已将其全部更改为“DrawText”,并已修复此问题。是的,其他行现在不起作用,但我现在正在添加该功能。谢谢 – 2014-11-23 16:38:59