简体   繁体   中英

Painting colored text to c++ win32

Is it possible to paint colored text to what I've already done?

I've tried WM_CTLCOLORSTATIC , CreateSolidBrush() , and several other functions.

//-----------------------------------
// Learning the win32 API for C++
//
// Created by: Cosmic Cruizer
//-----------------------------------

#include <windows.h>
#include <tchar.h>

// Function declarations
bool SetUpWindowClass (char*, int, int, int);         // Remove window structure from WinMain and put into function
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)  // Pre-declare Windows procedure/function

// Global variables
const char CLASS_NAME[] = "My Window Class Array";    // declared for window class; Can be static or const


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){
  //Step 1: Registering the Window Class
  HWND hwnd{};                                       // This is the handle for our window
  MSG msg{};                                         // Handle for messages to the application
  SetUpWindowClass (NULL, NULL, NULL, NULL);         // The Window structure - removed from main and made into a function

  // Step 2: Creating the Window
  hwnd = CreateWindowEx(             // returns a handle to the new window, or zero if the function fails
    WS_EX_CLIENTEDGE,                // Optional window styles. Can be set to 0
    CLASS_NAME,                      // Name of window class, see set 1b. Also set as the constant
    "My First C++ Windows App",      // Window title text
    WS_OVERLAPPEDWINDOW,             // Window style, title bar, a border, a system menu, and Minimize and Maximize buttons.
    200, 200, 500, 400,              // Size and position
    NULL, NULL, hInstance, NULL);    // Parent window, Menu, Instance handle, Additional app data

  // Add an exit button
   CreateWindow(
    "BUTTON",                        // Predefined class; Unicode assumed
    "EXIT",                          // Button text
    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles
    200, 200, 60, 25,                // x position, y position, Button width, Button height
    hwnd,                            // Parent window
    NULL,                            // No menu.
    (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);   // Pointer not needed.

  ShowWindow(hwnd, nCmdShow);        // Make the window visible on the screen


  // Step 3: The Message Loop
  while(GetMessage(&msg, NULL, 0, 0) != 0)  {       // Run the message loop. It will run until GetMessage() returns 0
    TranslateMessage(&msg);          // Translate virtual-key messages into character messages
    DispatchMessage(&msg);           // Send message to WindowProcedure
  }

  return msg.wParam;
}

//---------- Functions ----------//

// Setup the window structure
bool SetUpWindowClass (char *cpTitle, int iR, int iG, int iB) {
  //Step 1a:  The Window structure
  WNDCLASSEX wc{};                            // Data structure for the windowclass
  wc.cbSize            = sizeof(WNDCLASSEX);  // Sets the size of the Windows API
  wc.style             = 0;                   // define additional elements of the window class
  wc.lpfnWndProc       = WndProc;             // defines most of the behavior of the window. See setp 4 "LRESULT CALLBACK WndProc" function
  wc.cbClsExtra        = 0;                   // No extra bytes after the window class
  wc.cbWndExtra        = 0;                   // structure for the window instance
  wc.hInstance         = GetModuleHandle (NULL); // handle to the application instance.
  wc.hIcon             = LoadIcon(NULL, IDI_APPLICATION);   // handle to icon class, if NULL, system provides a default icon.
  wc.hCursor           = LoadCursor(NULL, IDC_ARROW);       // handle to cursor class
  wc.hbrBackground     = (HBRUSH)(COLOR_WINDOW+18);         // Add color as the background of the window
  wc.lpszMenuName      = NULL;                // No menu
  wc.lpszClassName     = CLASS_NAME;          // string that identifies the window class
  wc.hIconSm           = LoadIcon(NULL, IDI_APPLICATION);

  //Step 1b:  Register the window class, and if it fails quit the program
  if (RegisterClassEx (&wc)) return true;
  else return false;
}


// Step 4: the Window Procedure in this function
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
  switch(uMsg){
    case WM_CLOSE:{
      DestroyWindow(hwnd);
      break;
    }
    case WM_COMMAND:{               // Close the window when exit is pressed
      if (MessageBox(hwnd, "Really quit?", "Exit Warning", MB_OKCANCEL) == IDOK){ // what the hell, just wanted this.
        PostQuitMessage(0);
       }
         break;
    }
    case WM_DESTROY:{
      PostQuitMessage(0);
      break;
    }

//--- trying to create colored text ---//
    case WM_CTLCOLORSTATIC:{
      HDC hdcStatic = (HDC) wParam;             // handle to display context
      hwnd = (HWND) lParam; // handle to control window
      SetTextColor(hdcStatic, RGB(100,255,255));
      SetBkColor(hdcStatic, RGB(250,250,6));
      return (INT_PTR)CreateSolidBrush(RGB(250,250,100));
    }
    case WM_CTLCOLOREDIT:{
      HDC hdcStatic = (HDC) wParam;
      SetTextColor(hdcStatic, RGB(0,0,255));
      SetBkColor(hdcStatic, RGB(0,230,0));
      return (INT_PTR)CreateSolidBrush(RGB(0,230,0));
    }


    case WM_PAINT:{                     // All painting (text) occurs here, between BeginPaint and EndPaint.
      PAINTSTRUCT ps;                   // Holds info about current painting session.
      HDC hdc = BeginPaint(hwnd, &ps);  // Create the device context (DC)

      // Each character is added to the cpaText array. Then the for loop goes through and paints each character
      int iY = 7;                       // Vertical spaces and number of lines for the array
      const char *cpaText [iY] = {      // changed from char to const char to get rid of warning. and added 1 for each line and a return
        "Hello Peoples",
        "",
        "This is my first attempt to program using the Win32 API.",
        "I can only hope it gets better with time.",
        "",
        "Created by \"The\" Cosmic Cruizer"
      };
      for (int iLoopCounter = 0; cpaText [iLoopCounter] != 0; iLoopCounter++, iY += 20) {
        TextOut (hdc, 5, iY, cpaText [iLoopCounter], strlen (cpaText [iLoopCounter]));
      }

      EndPaint(hwnd, &ps);              // Free up HDC created with BeginPaint
      break;
    }
    default:{
      return DefWindowProc(hwnd, uMsg, wParam, lParam); // Return is needed either here or at the end
      break;
    }
  }

  return DefWindowProc(hwnd, uMsg, wParam, lParam); // Return is needed either here or in the default case
}

WM_CTLCOLORSTATIC and WM_CTLCOLOREDIT are notification messages used by STATIC / EDIT controls, neither of which you have on your window, so you will never receive those messages and should remove those handlers from your code.

You are trying to draw colored text directly onto your window using TextOutA() in a WM_PAINT handler, which is fine. But per the TextOutA() documentation :

The TextOut function writes a character string at the specified location, using the currently selected font, background color, and text color.

Your WM_PAINT handler is not selecting anything into the HDC that BeginPaint() returns, before trying to draw on it. It simply needs to configure the desired font/color values as desired, eg:

HFONT hFont;

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
  switch(uMsg){
    ...
    case WM_CREATE:{
      hFont = CreateFont(...); // or CreateFontIndirect()
      break;
    }

    case WM_DESTROY:{
      DeleteObject(hFont);
      PostQuitMessage(0);
      break;
    }

    case WM_SETTINGCHANGE:
    case WM_FONTCHANGE:{
      DeleteObject(hFont);
      hFont = CreateFont(...); // or CreateFontIndirect()
      InvalidateRect(hwnd, NULL, TRUE);
      break;
    }

    case WM_PAINT:{
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint(hwnd, &ps);

      HFONT hOldFont = (HFONT) SelectObject(hdc, hFont);
      SetTextColor(hdc, ...);
      SetBkColor(hdc, ...);

      int iY = 7;
      const char *cpaText [iY] = {
        "Hello Peoples",
        "",
        "This is my first attempt to program using the Win32 API.",
        "I can only hope it gets better with time.",
        "",
        "Created by \"The\" Cosmic Cruizer"
      };
      for (int iLoopCounter = 0; cpaText [iLoopCounter] != 0; iLoopCounter++, iY += 20) {
        TextOutA (hdc, 5, iY, cpaText [iLoopCounter], strlen (cpaText [iLoopCounter]));
      }

      SelectObject(hdc, hOldFont);

      EndPaint(hwnd, &ps);
      return 0;
    }
    ...
  }

  return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM