Steve Hatcher
Steve Hatcher

Reputation: 715

Backspace functionality in keyboard input program

I am learning win32 programming and have set myself a simple text edit program as first task.

The program is largely based on this demo (under the Displaying Keyboard Input section)

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

I wanted to modify this program since it does not process the backspace key. I found this code which does (under Processing Keyboard Input):

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

but goes about it quite a different way. It seems to be based on the Petzold book. The problem with this code is everytime the window is resized it wipes the current input. I want a program that allows input, backspace, and does not wipe text on WM_SIZE.

So I want about modifying the original code based on this Petzold version.

Essentially all I changed was:

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

to

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;

and added a VK_DELETE WM_KEYDOWN case that does this:

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;

upon first compile it seems to work fine. The backspaces properly remove the text. But I am running into a few glitches that I do not the cause of.

Firstly, if I type something like the following:

input text

after a few backspaces the caret and text wont go the correct character length back as shown (part of the s is still visible):

part of s showing

This only happens sometimes, not all the times.

Secondly, resizing the window sometimes causes parts of the text to disappear, not all of it. Usually its text after a space is entered. But I need to compile the program a few times to get this to happen.

Any tips on whats going on would be greatly appreciated. Thanks

Upvotes: 0

Views: 1212

Answers (1)

Jonathan Potter
Jonathan Potter

Reputation: 37132

I think the problem is that in your VK_DELETE handler you're not repainting the display properly. I could get it to go wrong every time by moving the cursor to the middle of the text I'd entered and then pressing the Delete key. The code seems to assume that only the last character in the line is being erased but this isn't always the case.

Try changing it to this:

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

That will let the display get repainted completely by your WM_PAINT handler, and at least for me that seems to make it work ok (on a single line that is - as soon as the text wraps to two lines you have other problems).

If you verify that this solves the issue then you could either stick with this solution, or redesign your VK_DELETE handler to properly clear out the deleted text and repaint the line.

Upvotes: 1

Related Questions