How to Update Text Using TextOut() in C++

How to Update Text Using TextOut() in C++

The TextOut() function in C++ uses the selected font, background color, and text color to write a character string at the specified location. It belongs to the #include <wingdi.h>.

In this tutorial, you shall learn how to update any text using the TextOut() function in C++.

An interesting idea to use and update the current position each time the C++ program calls the TextOut() function for a specified device is to use the SetTextAlign function using the fMode parameter set to the TA_UPDATECP (it will enable you to permit the system). The wingdi.h header file defines the TextOut() function as an alias that automatically detects the ANSI or the Unicode versions of your OS or processor to select the suitable version of this function.

Use the Source of the Text String to Update the Text Using the TextOut() Function in C++

A TextOut() function can have five parameters, including [in] hdc to handle device context, [in] x to represent the x-coordinate, [in] y to represent the y-coordinates, [in] IpString as a pointer to the string, and [in] c to define the length of the string. If this function executes perfectly, it returns a non-zero value; otherwise, a null or 0 is produced.

Furthermore, the interpretation of the reference point is directly-proportional and dependent on the latest (current) text-alignment mode of the C++ program. However, you can retrieve the current text-alignment mode by calling the GetTextAlign function.

// displaying text
#include <windows.h>

// define `#include <wingdi.h>` separately or the `windows.h` is an alternative

DWORD text_repaintcount = 0;  // to handle the color_code of the primary text

// a call back to the pre-defined function defined in the `windows.h` header
// file
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,
                         LPARAM);  // initialize the handle, `typedef UNIT`,
                                   // `typedef UNIT_PTR`, and `typeof LONG_PTR`

int WINAPI WinMain(HINSTANCE obj_instance_hi, HINSTANCE hInstance_prevent,
                   LPSTR lp_cmd_imp, int show_cmd_new) {
  WNDCLASSEX obj_windclass;
  MSG obj_showmessage;
  obj_windclass.cbSize = sizeof(WNDCLASSEX);
  obj_windclass.style = 0;
  obj_windclass.lpfnWndProc = WndProc;
  obj_windclass.cbClsExtra = 0;
  obj_windclass.cbWndExtra = 0;
  obj_windclass.hInstance = obj_instance_hi;
  obj_windclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  obj_windclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  obj_windclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  obj_windclass.lpszMenuName = NULL;
  obj_windclass.lpszClassName = TEXT("New Window!");
  obj_windclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

  RegisterClassEx(&obj_windclass);
  CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("New Window!"), TEXT("Text Output"),
                 WS_VISIBLE | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                 850, 350, NULL, NULL, obj_instance_hi, NULL);

  while (GetMessage(&obj_showmessage, NULL, 0, 0) > 0) {
    TranslateMessage(&obj_showmessage);
    DispatchMessage(&obj_showmessage);
  }

  return obj_showmessage.wParam;
}

LRESULT CALLBACK WndProc(HWND obj_hwnd_pri, UINT obj_message_show,
                         WPARAM obj_wparma_sec, LPARAM obj_iparma_sec) {
  PAINTSTRUCT obj_paint_structure;
  HDC obj_HDC_pri;
  SIZE text_updated_size;
  TCHAR obj_string[100] = TEXT("\0");
  HFONT text_update_font;
  HBRUSH text_update_hbrush;
  TEXTMETRIC text_metric;

  int temp_y = 0;
  int temp_x = 0;
  int text_update_length;

  switch (obj_message_show) {
    case WM_PAINT:  // it traps the paint message

      // the following outputs the text using the default font and other
      // settings
      obj_HDC_pri = BeginPaint(obj_hwnd_pri, &obj_paint_structure);
      int obj_hDC_last;
      obj_hDC_last =
          SaveDC(obj_HDC_pri);  // save the current operating device context
      text_update_length = wsprintf(obj_string, TEXT("Stock font"));
      TextOut(obj_HDC_pri, 0, temp_y, obj_string, text_update_length);

      // updating text using the `ANSI_FIXED_PONT` and outputting the text
      GetTextMetrics(obj_HDC_pri, &text_metric);
      temp_y =
          temp_y +
          text_metric
              .tmHeight;  // calculate new vertical coordinate using text metric

      text_update_hbrush = (HBRUSH)GetStockObject(ANSI_FIXED_FONT);

      SelectObject(obj_HDC_pri, text_update_hbrush);
      text_update_length = wsprintf(obj_string, TEXT("ANSI_FIXED_FONT"));
      TextOut(obj_HDC_pri, 0, temp_y, obj_string, text_update_length);

      // changing the primary color of the text and producing it as an output
      GetTextMetrics(obj_HDC_pri, &text_metric);
      temp_y = temp_y + text_metric.tmHeight;

      COLORREF textcolor_new;
      textcolor_new = COLORREF RGB(255, 0, 0);

      SetTextColor(obj_HDC_pri, textcolor_new);
      text_update_length =
          wsprintf(obj_string, TEXT("ANSI_FIXED_FONT, color red"));
      TextOut(obj_HDC_pri, temp_x, temp_y, obj_string, text_update_length);

      // changing the background color of the text to blue and producing it as
      // an output
      GetTextMetrics(obj_HDC_pri, &text_metric);
      temp_y = temp_y + text_metric.tmHeight;

      COLORREF text_update_backgroundcolor;
      text_update_backgroundcolor = COLORREF RGB(0, 0, 255);

      SetBkColor(obj_HDC_pri, text_update_backgroundcolor);
      text_update_length = wsprintf(
          obj_string, TEXT("ANSI_FIXED_FONT, color red with blue background"));
      TextOut(obj_HDC_pri, temp_x, temp_y, obj_string, text_update_length);

      // set the background of the text transparent and produce it as an output
      GetTextMetrics(obj_HDC_pri, &text_metric);
      temp_y = temp_y + text_metric.tmHeight;
      SetBkMode(obj_HDC_pri, TRANSPARENT);

      SelectObject(obj_HDC_pri, text_update_hbrush);
      text_update_length = wsprintf(
          obj_string, TEXT("ANSI_FIXED_FONT,color red transparent background"));
      TextOut(obj_HDC_pri, 0, temp_y, obj_string, text_update_length);

      // changing the font of the text to `Arial` and changing its size to
      // output
      GetTextMetrics(obj_HDC_pri, &text_metric);
      temp_y = temp_y + text_metric.tmHeight;
      text_update_font =
          CreateFont(20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Ariel"));

      SelectObject(obj_HDC_pri, text_update_font);
      text_update_length = wsprintf(
          obj_string,
          TEXT("ANSI_FIXED_FONT, color red, transparent background,arial 20"));
      TextOut(obj_HDC_pri, 0, temp_y, obj_string, text_update_length);

      // use the saved value to restore the original font size, style, and other
      // settings
      GetTextMetrics(obj_HDC_pri, &text_metric);
      temp_y = temp_y + text_metric.tmHeight;

      RestoreDC(obj_HDC_pri, obj_hDC_last);
      text_update_length = wsprintf(
          obj_string, TEXT("stock font restored using SaveDC/RestoreDC"));
      TextOut(obj_HDC_pri, temp_x, temp_y, obj_string, text_update_length);
      GetTextMetrics(obj_HDC_pri, &text_metric);
      temp_y = temp_y +
               text_metric.tmHeight;  // calculating the vertical co-ordinates
                                      // using the `text_metric`

      // changing font to `new roman` and size to `30` and producing an output
      int obj_text_baseline;  // calculate the baseline of the font
      text_update_font = CreateFont(30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                    TEXT("Times New Roman"));

      SelectObject(obj_HDC_pri, text_update_font);
      GetTextMetrics(obj_HDC_pri, &text_metric);
      obj_text_baseline = text_metric.tmAscent;
      text_update_length =
          wsprintf(obj_string, TEXT("times new roman 30 statement 1"));
      TextOut(obj_HDC_pri, temp_x, temp_y, obj_string, text_update_length);
      GetTextExtentPoint32(obj_HDC_pri, obj_string, text_update_length,
                           &text_updated_size);
      temp_x = temp_x + text_updated_size.cx;

      // change the font into `courier new` and the size to `20` and output the
      // updated text
      int text_changefont_baselinecourier;
      text_update_font = CreateFont(20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                    TEXT("Courier New"));

      SelectObject(obj_HDC_pri, text_update_font);
      GetTextMetrics(obj_HDC_pri, &text_metric);
      text_changefont_baselinecourier =
          obj_text_baseline - text_metric.tmAscent;
      text_update_length = wsprintf(obj_string, TEXT("Courier statement "));
      TextOut(obj_HDC_pri, temp_x, temp_y + text_changefont_baselinecourier,
              obj_string, text_update_length);
      GetTextExtentPoint32(obj_HDC_pri, obj_string, lstrlen(obj_string),
                           &text_updated_size);
      temp_x = temp_x + text_updated_size.cx;

      // changing the font to `ariel` and size to `20` and output the updated
      // text
      int text_fontchange_baselinearial;
      text_update_font =
          CreateFont(10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Ariel"));

      SelectObject(obj_HDC_pri, text_update_font);
      GetTextMetrics(obj_HDC_pri, &text_metric);
      text_fontchange_baselinearial = obj_text_baseline - text_metric.tmAscent;
      text_update_length = wsprintf(obj_string, TEXT("ariel 10 statement 3 "));
      TextOut(obj_HDC_pri, temp_x, temp_y + text_fontchange_baselinearial,
              obj_string, text_update_length);

      EndPaint(obj_hwnd_pri, &obj_paint_structure);
      DeleteDC(obj_HDC_pri);
      DeleteObject(text_update_font);
      DeleteObject(text_update_hbrush);
      break;

    case WM_CLOSE:
      DestroyWindow(obj_hwnd_pri);
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(obj_hwnd_pri, obj_message_show, obj_wparma_sec,
                           obj_iparma_sec);
  }

  return 0;
}

Output:

https://drive.google.com/file/d/1YUs55n-gw1rYgOrBce0RAuuET5UPdTLa/view?usp=sharing

Declare the source for the text string to display the updated text using the TextOut() function when handling the WM_PAINT on Windows C++ applications. The C++ code from this tutorial does not work on its own, but with proper Windows, user interface either using Visual Studio or .dsp, .dsw, .ncb, and .opt files combined to display a proper dialog box on Windows.

The Windows API changed with the new version of Windows, and current versions require an L modifier as in L"wchar_ttext. This C++ code is tested using Visual Studio 2019 on Windows 10.

Furthermore, generate the skeleton for a Windows Desktop GUI application with the wWinMain(), myRegisterClass(), InitInstance(), and WndProc() and use the font into the HDC for drawing the text and use the TextOut() function to draw the text with the new updated font.

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub