c++ - 将彩色文本绘制到 c++ win32
问题描述
是否可以将彩色文本绘制到我已经完成的内容上?
我已经尝试过WM_CTLCOLORSTATIC
,CreateSolidBrush()
和其他几个功能。
//-----------------------------------
// 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
并且WM_CTLCOLOREDIT
是STATIC
/EDIT
控件使用的通知消息,您的窗口上都没有,因此您将永远不会收到这些消息,并且应该从您的代码中删除这些处理程序。
您正在尝试使用处理程序将彩色文本直接绘制到您的窗口上TextOutA()
,WM_PAINT
这很好。但根据TextOutA()
文档:
TextOut 函数使用当前选择的字体、背景颜色和文本颜色在指定位置写入字符串。
在尝试绘制之前,您的WM_PAINT
处理程序没有选择返回的任何内容。它只需要根据需要配置所需的字体/颜色值,例如:HDC
BeginPaint()
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);
}
推荐阅读
- java - 如何使用android视频时间戳(java)在某个视频帧触发活动
- android - 如何在 Kotlin 中使用数据绑定检测双击?
- python - 无法将 Jupiter Notebooks 转换为 Python 脚本 Jupyter 命令 `jupyter-nbconvert` 未找到
- python - 如何覆盖cleaned_data中的变量
- android - Redmi 手机上的启动映像标题字段无效
- amazon-web-services - 从 Redshift 调用 Lambda UDF 时出错
- chart.js - 预期的类型来自属性 'XAxes' 和 'yAxes',在类型 '_DeepPartialObject<{ [key: string] 上声明:
- python - 如何通过基于字典的共享列合并两个数据框?
- python - 如何为 Django 中的多对多字段添加值
- python - 如何在 django 中安装模板?我将模板连接到视图文件和设置文件中。然后我用渲染来显示模板