简体   繁体   English

将彩色文本绘制到 c++ win32

[英]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.我试过WM_CTLCOLORSTATICCreateSolidBrush()和其他几个函数。

//-----------------------------------
// 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. WM_CTLCOLORSTATICWM_CTLCOLOREDITSTATIC / EDIT控件使用的通知消息,您的窗口中都没有,因此您永远不会收到这些消息,应该从代码中删除这些处理程序。

You are trying to draw colored text directly onto your window using TextOutA() in a WM_PAINT handler, which is fine.您正在尝试使用WM_PAINT处理程序中的TextOutA()将彩色文本直接绘制到您的窗口上,这很好。 But per the TextOutA() documentation :但根据TextOutA()文档

The TextOut function writes a character string at the specified location, using the currently selected font, background color, and text color. TextOut 函数使用当前选择的字体、背景颜色和文本颜色在指定位置写入字符串

Your WM_PAINT handler is not selecting anything into the HDC that BeginPaint() returns, before trying to draw on it.在尝试对其进行绘制之前,您的WM_PAINT处理程序未将任何内容选择到BeginPaint()返回的HDC中。 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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