Question

I do not see where the error is. The window display only the first character you type, and the other is not. Although the cursor moves when typing. And when minimize and maximize the window, the text becomes visible.

#include <windows.h>
#define IDI_MYICON 201
#define IDR_MYMENU 201
#define ID_FIO_FirstName 4002
#define ID_FIO_SecondName 4003
#define ID_FIO_Name 4001
#define ID_INFO_DeveloperStatus 9002
#define ID_INFO_LearningForm 9003
#define ID_INFO_Group 9004
#define BUFSIZE 6665535
#define SHIFTED 0x8000
const char g_szClassName[] = "MFW";
LONG APIENTRY WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc; 
    TEXTMETRIC tm;
    static DWORD dwCharX;
    static DWORD dwCharY;
    static DWORD dwClientX;
    static DWORD dwClientY;
    static DWORD dwLineLen;
    static int nCaretPosX = 0;
    static int nCaretPosY = 0;
    static int nCharWidth = 0;
    static int cch = 0;
    static int nCurChar = 0;
    static PTCHAR pchInputBuf;
    int i, j; 
    int cCR = 0;  
    int nCRIndex = 0;
    int nVirtKey; 
    TCHAR szBuf[128];
    TCHAR ch; 
    PAINTSTRUCT ps;
    RECT rc; 
    SIZE sz;
    COLORREF crPrevText;
    COLORREF crPrevBk;
    switch(Message)
    {
        case WM_CREATE:
      {
        hdc = GetDC(hwnd);
        GetTextMetrics(hdc, &tm);
        ReleaseDC(hwnd, hdc);
        dwCharX = tm.tmAveCharWidth;
        dwCharY = tm.tmHeight;
        pchInputBuf=(LPTSTR)GlobalAlloc(GPTR,BUFSIZE*sizeof(TCHAR));
          HMENU hMenu, hSubMenu;
          HICON hIcon, hIconSm;
          hMenu = CreateMenu();
          hSubMenu = CreatePopupMenu();
          AppendMenu(hSubMenu, MF_STRING, ID_FIO_FirstName, "FirstName");
          AppendMenu(hSubMenu, MF_STRING, ID_FIO_SecondName, "SecondName");
          AppendMenu(hSubMenu, MF_STRING, ID_FIO_Name, "Name");
          AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&FIO");
          hSubMenu = CreatePopupMenu();
          AppendMenu(hSubMenu, MF_STRING, ID_INFO_DeveloperStatus, "DeveloperStatus");
          AppendMenu(hSubMenu, MF_STRING, ID_INFO_LearningForm, "LearningForm");
          AppendMenu(hSubMenu, MF_STRING, ID_INFO_Group, "Group");
          AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&INFO");
          SetMenu(hwnd, hMenu);
          hIcon =(HICON)LoadImage(NULL, "my_icon.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
            if(hIcon)
              SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
            else
            MessageBox(hwnd, "Could not load large icon!","Error", MB_OK | MB_ICONERROR);
          hIconSm =(HICON)LoadImage(NULL, "my_icon.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
            if(hIconSm)
              SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
            else
            MessageBox(hwnd, "Could not load small icon!","Error", MB_OK | MB_ICONERROR);
        break;
    }
    break;
    case WM_PAINT:
              if (cch==0)break;
              hdc=BeginPaint(hwnd,&ps);
              HideCaret(hwnd);
              SetRect(&rc, 0, 0, dwLineLen, dwClientY);
              DrawText(hdc, pchInputBuf,-1,&rc,DT_NOCLIP);
              ShowCaret(hwnd);
              EndPaint(hwnd, &ps);
              break;
    case WM_SIZE:
        dwClientX=LOWORD(lParam);
        dwClientY = HIWORD(lParam);
        dwLineLen=dwClientX-dwCharX;
        break;
          case WM_SETFOCUS:
              CreateCaret(hwnd, (HBITMAP) 0,3, dwCharY);
              SetCaretPos(nCaretPosX,nCaretPosY*dwCharY);
              ShowCaret(hwnd);
              break;
          case WM_KILLFOCUS:
              HideCaret(hwnd);
              DestroyCaret();
              break;
    case WM_CHAR:
              if (cch > BUFSIZE-5)
              {
                pchInputBuf[cch] = 0x00;
                SendMessage(hwnd,WM_PAINT, 0, 0);
                }
                switch (wParam)
                {
                    case 0x08:
                    case 0x0A:
                    case 0x1B:
                      MessageBeep(0xFFFFFFFF);
                      return 0;
                  case 0x09:
                      for (i = 0; i < 4; i++)
                          SendMessage(hwnd, WM_CHAR, 0x20, 0);
                      return 0;
                  case 0x0D:
                      pchInputBuf[cch++] = 0x0D;
                      nCaretPosX = 0;
                      nCaretPosY += 1;
                      break;
                  default:
                      ch =(TCHAR)wParam;
                      HideCaret(hwnd);
                      hdc = GetDC(hwnd);
                      GetCharWidth32(hdc,wParam,wParam,&nCharWidth);
                      DrawText(hdc, pchInputBuf,-1,&rc, DT_NOCLIP);
                      ReleaseDC(hwnd, hdc);
                      pchInputBuf[cch++] = ch;
                      nCaretPosX += nCharWidth;
                      if ((DWORD) nCaretPosX > dwLineLen)
                      {
                          nCaretPosX = 0;
                          pchInputBuf[cch++] = 0x0D;
                          ++nCaretPosY;
                      }
                      nCurChar = cch;
                      ShowCaret(hwnd);
                      break;
              }
              SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
              break;
    case WM_KEYDOWN:
    switch (wParam)
      {
         case VK_LEFT:
             if (nCaretPosX > 0)
             {
                HideCaret(hwnd);
                ch = pchInputBuf[--nCurChar];
                hdc = GetDC(hwnd);
                GetCharWidth32(hdc, ch, ch, &nCharWidth);
                ReleaseDC(hwnd, hdc);
                nCaretPosX = max(nCaretPosX - nCharWidth, 0);
                ShowCaret(hwnd);
} break;
         case VK_RIGHT:
         if (nCurChar > cch) {
                    HideCaret(hwnd);
                    ch = pchInputBuf[nCurChar];
                    if (ch == 0x0D) {
                        nCaretPosX = 0;
                        nCaretPosY++;
                    }
                    else {
                        hdc = GetDC(hwnd);
                        nVirtKey = GetKeyState(VK_SHIFT);
                        if (nVirtKey & SHIFTED) {
                        crPrevText = SetTextColor(hdc,RGB(255, 255, 255));
                        crPrevBk = SetBkColor(hdc,RGB(0,0,0));
                        TextOut(hdc, nCaretPosX,nCaretPosY * dwCharY,&ch,1);
                        SetTextColor(hdc, crPrevText);
                        SetBkColor(hdc, crPrevBk);
                        }
                        GetCharWidth32(hdc, ch, ch, &nCharWidth);
                        ReleaseDC(hwnd, hdc);
                        nCaretPosX = nCaretPosX + nCharWidth;
                    }
                    nCurChar++;
                    ShowCaret(hwnd);
                    break;
                }
                break;
           case VK_HOME:
              nCaretPosX = nCaretPosY = 0;
              nCurChar = 0;
           break;
           case VK_END:
              for (i=0; i < cch; i++)
              {
                if (pchInputBuf[i] == 0x0D) {
                   cCR++;
                   nCRIndex = i + 1;
                }
              }
              nCaretPosY = cCR;
              for (i = nCRIndex, j = 0; i < cch; i++, j++)
              szBuf[j] = pchInputBuf[i];
              szBuf[j] = TEXT('\0');
              hdc = GetDC(hwnd);
                GetTextExtentPoint32(hdc,szBuf,lstrlen(szBuf),&sz);
                nCaretPosX = sz.cx;
                ReleaseDC(hwnd, hdc);
                nCurChar = cch;
                break;
                default:
             break;
             }
             SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
             break;

    case WM_COMMAND:
            switch(LOWORD(wParam))
            {
        case ID_FIO_FirstName:
            MessageBox(hwnd, "F-3", "FirstName", 0);
        break;
        case ID_FIO_SecondName:
            MessageBox(hwnd, "B-2", "SecondName", 0);
        break;
        case ID_FIO_Name:
            MessageBox(hwnd, "A-1", "Name", 0);
        break;
        case ID_INFO_DeveloperStatus:
            MessageBox(hwnd, "S", "DeveloperStatus", 0);
        break;
        case ID_INFO_LearningForm:
        MessageBox(hwnd, "FORM", "LearningForm", 0);
        break;
        case ID_INFO_Group:
        MessageBox(hwnd, "GR", "Group", 0);
        break;
            }
        break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
            GlobalFree((HGLOBAL) pchInputBuf);
            UnregisterHotKey(hwnd, 0xAAAA);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
WNDCLASSEX wc;
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_MYICON));
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MYMENU);
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = (HICON)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_MYICON),IMAGE_ICON,16,16, 0);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
hwnd = CreateWindowEx(
        WS_EX_OVERLAPPEDWINDOW,
        g_szClassName,
        "QWERTY",
        WS_OVERLAPPEDWINDOW,
        200, 100, 800, 600,
        NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG Msg;
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
Was it helpful?

Solution

You use WM_PAINT incorrectly. You shouldn't send it manually. You need to call InvalidateRect(hwnd, NULL, true); instead of SendMessage(hwnd,WM_PAINT, 0, 0); and it will post a WM_PAINT message to your WndProc correctly.
When you minimize/maximize the window, Windows call internally something like InvalidateRect(hwnd, NULL, true);

Addition by manuell:
Also always call BeginPaint/EndPaint in WM_PAINT handler (you shouldn't break before calling BeginPaint/EndPaint).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top