2014-11-22 223 views
0

我正在學習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

回答

1

我認爲問題是,在您的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