Reputation: 715
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:
after a few backspaces the caret and text wont go the correct character length back as shown (part of the s is still visible):
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
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