在c++ (WinAPI或QT)中打印文本和图像

Print text and images in C++ (WinAPI or QT)

本文关键字:打印 文本 图像 QT c++ WinAPI      更新时间:2023-10-16

在一个基本的程序,我需要知道如何使文本显示小部件和图像显示,既可以更改为不同的字符串和图像上的命令。这些将显示在一个基本的GUI上。

任何具体的帮助将非常感激,因为我已经被困在这个超过10周!这是我最后的办法了。

我正在做一个基本的程序,问问题(这是我想要打印的文本)和图像的问题出现在它下面。我已经成功地在控制台命令窗口中制作了这个程序(我将在下面分享代码),但这当然意味着不能显示图像,所以我不得不在支持图像的GUI中重新制作它。

这是我用c++完成的第一个项目,我只知道一些基础知识(我有限的知识让我在没有帮助的情况下完成了控制台命令窗口程序)。

我第一次使用WinAPI,因为它是我的计算机在microsoft visual studio中附带的,并尝试了许多不同的建议,其他人已经回答了类似的问题,但总是有两个问题之一;1. 他们提供的代码有许多错误,其中大多数是"_是未定义的"或没有正确导入,或2。成功地创建了基本文本,但没有指定如何在创建后更改它(到目前为止,我没有成功的图像打印)。我已经尝试了3个问题/答案从cplusplus.com和3从堆栈溢出(链接将在下面),他们都有这2个问题是由于我缺乏c++ bug修复技能创建的。

使用WinAPI的建议将优于QT,因为我不知道我在QT中做什么,并在导入代码时获得两位数的错误值(即使我导入正确的目录),而WinAPI不会获得导入错误。

命令控制台程序代码:
//G-Learning
//@author: James Monk
//@completed: 7/6/16
//@version 1.0
//These are the libraries (external files) to include at the start.
#include <cstdio>
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
using namespace std;
//Defining the [global] variables that will be used throughout the program
int running = 1;
int menuSelection;
int questionsLeft = 5;
int questionTextPicked;
int questionImagePicked;
int questionRandomised;
int score = 0;
int userInput;
int userInputDummy;
string stringPointer;
int intPointer;
string questionText[10] = {
    "Would this most likely be, (1) an enemy (2) a player?n",
    "Is this (1) how many hearts the player has inside their body, or (2) a number of lives the player has?n", 
    "Is this (1) a health bar, or (2) a set of red lights?n",
    "Is this (1) a money counter, or (2) a yellow ball counter?n",
    "Would this be a good object to touch with your character? (1) no or (2) yes?n",
    "What would this object likely have in it? (1) rewards, or (2) punishmentsn", 
    "What does 'Game Over' mean? (1) your session has ended, or (2) the game is no longer playablen", 
    "What would an icon like this likely be for? (1) show wheels, or (2) optionsn", 
    "In a racing game, what would this be for? (1) health bar, or (2) fuel tank metern", 
    "What would this button likely do? (1) exit or cancel, or (2) mark a spot with an xn" };
//Defining what happens with the different functions
void introduction() {
    printf("nG-Learning is a program built to teach people who know little about games the basic features of them. nn
Questions will be asked, and you will need to answer them by choosing the correct answer.n
You will need to press 1, 2, or 3 followed by enter to choose.nn
Press any number key followed by enter to return to the main menu.nn");
    cin >> userInputDummy;
    menuSelection = 0;
}
void start() {
    printf("nThe questions will now start, good luck!nn");
    while (questionsLeft > 0) {
        questionTextPicked = (rand() % 10);
        if (questionTextPicked == 0) {
            questionRandomised = (rand() % 4);
            questionImagePicked = (7 + questionRandomised);
        } 
        else if (questionTextPicked == 4) {
            questionRandomised = (rand() % 3);
            questionImagePicked = (11 + questionRandomised);
        }
        else {
            questionImagePicked = questionTextPicked;
        }
        printf("after calculations, questionTextPicked is %d, questionRandomised is %d, and questionImagePicked is %dnn", questionTextPicked, questionRandomised, questionImagePicked);
        //answering questions should be here
        stringPointer = questionText[questionTextPicked];
        intPointer = questionAnswer[questionImagePicked];
        printf("answerswer is %dnn", intPointer);
        printf("%sn", stringPointer, intPointer);
        printf("answerswer is %dnn", intPointer);
        cin >> userInput;
        if (userInput == questionAnswer[questionImagePicked]) {
            printf("nCorrect!nn");
            score++;
        }
        else {
            printf("nIncorrect answer.nn");
        }
        questionsLeft--;
        if (questionsLeft > 0) {
            printf("%d questions to go!nn", questionsLeft);
        }
        if (questionsLeft == 0) {
            printf("All questions have been answered, you scored %d/5.nnReturning you to the main menunn", score);
            score = 0;
        }
    } //end of start's while loop
    menuSelection = 0;
} //end of start's function
void exit() {
    menuSelection = 0;
    running = 0;
}
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    //Main function, where everything starts
    int main(int argc, char ** argv) {
        while (running == 1) {
            //Welcoming the user to the program, and asking them what they want to do (starts functions)
            printf("welcome to G-Learning! Press a key to get started.n1: Instructionsn2: Startn3: Exitnn");
            questionsLeft = 5; //Resetting this so that the start function can begin again
            cin >> menuSelection;
            if (menuSelection == 1) {
                introduction();
            }
            else if (menuSelection == 2) {
                start();
            }
            else if (menuSelection == 3) {
                exit();
            }
            else {
                printf("Invalid input, please use the 1, 2, or 3 key.");
            }
        }
        return 0;
        return EXIT_SUCCESS;
    } //end of main function

我最好的WinAPI迭代代码(可以打印文本,但不能再次在命令上;也没有图像功能。我想知道如何改进这个!):

//These are the libraries (external files) to include at the start.
#include <cstdio>
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
using namespace std;
int textHorizontal = 10;
int textVertical = 10;
//Variables used in making the program window
int numberInput;
char charictorInput;
string stringInput;
const char g_szClassName[] = "myWindowClass";
HINSTANCE hInstance;
// Function to get the size of the text
int GetTextSize(LPSTR a0)
{
    for (int iLoopCounter = 0; ; iLoopCounter++)
    {
        if (a0[iLoopCounter] == '')
            return iLoopCounter;
    }
}
LPSTR TextArray[] = {
    "Hello World"
};
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        TextOut(hdc,
            // Location of the text
            textHorizontal,
            textVertical,
            // Text to print
            TextArray[0],
            // Size of the text, my function gets this for us
            GetTextSize(TextArray[0]));
        EndPaint(hwnd, &ps);
    }
    break;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int WINAPI WinMain(HINSTANCE hInstanace, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX WindowClass;
    WindowClass.cbClsExtra = 0;
    WindowClass.cbWndExtra = 0;
    WindowClass.cbSize = sizeof(WNDCLASSEX);
    WindowClass.lpszClassName = "1";
    WindowClass.lpszMenuName = NULL;
    WindowClass.lpfnWndProc = WndProc;
    WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WindowClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WindowClass.style = 0;
    WindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    RegisterClassEx(&WindowClass);
    HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
        "1",
        "G-Learning by James Monk",
        WS_OVERLAPPEDWINDOW,
        315, 115,
        1080, 720,
        NULL,
        NULL,
        hInstance,
        NULL);
    ShowWindow(hwnd, SW_SHOWNORMAL);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        if (VK_ESCAPE == msg.wParam)
            break;
    }
    return 0;
}

我仅限于2个链接,所以要查看我尝试的3个cplusplus.com页面和我尝试的3个堆栈溢出页面,链接到它们的谷歌文档在这里:https://docs.google.com/document/d/1IX2hxzAVka3UmVkaAgv-gXv_cwwmP3FkTYQuFWrrqyE/edit?usp=sharing

如何将QT安装到Microsoft Visual Studio中:https://www.youtube.com/watch?v=P6Mg8FpFPS8

感谢您阅读我的问题,甚至提前更多的帮助!

HINSTANCE hInstance;
int WINAPI WinMain(HINSTANCE hInstanace...
CreateWindowEx(... hInstance ...)

这里有拼写错误。hInstanacehInstance不一样。Visual Studio应该给你警告。将警告级别设置为4。处理所有警告并修复它们。只有在极少数情况下才可以忽略警告。

此外,在声明WNDCLASSEX WindowClass;时,您错过了初始化hInstance,因此代码将无处可去。在c++ 14中你可以这样做

WNDCLASSEX WindowClass = {0}

将所有成员初始化为0。在堆栈上声明数据时,总是尝试这样做。也要避免在消息循环中放入随机代码。

#include <cstdio>
#include <iostream>
#include <windows.h>

以上头文件用于C输入/输出、c++输入/输出和WinAPI。通常你不需要所有的。选择一个.

LPSTR TextArray[] = {
    "Hello World"
};
上面的

是一个字符数组,或者只是"text"。如果你访问TextArray[0],它会给你字符'H'

int GetTextSize(LPSTR a0)
{
    for (int iLoopCounter = 0; ; iLoopCounter++)
    {
        if (a0[iLoopCounter] == '')
            return iLoopCounter;
    }
}

以上代码相当于strlen。你的代码到处都是。你有像std::string这样的c++ 14类,C头文件,像GetTextSize这样无用的函数(主要用于学习C/c++),更高级的WinAPI,以及一些提到的Qt交叉开发。我建议你花更多的时间阅读c++书籍。下面是你要做的事情的例子:

#include <windows.h>
#include <string>
#include <vector>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HWND combobox;
    static std::vector<std::string> vec = {
        "Would this most likely be, (1) an enemy (2) a player?n",
        "Is this (1) how many hearts the player has inside their body, or (2) a number of lives the player has?n",
        "Is this (1) a health bar, or (2) a set of red lights?n",
        "Is this (1) a money counter, or (2) a yellow ball counter?n",
        "Would this be a good object to touch with your character? (1) no or (2) yes?n",
        "What would this object likely have in it? (1) rewards, or (2) punishmentsn",
        "What does 'Game Over' mean? (1) your session has ended, or (2) the game is no longer playablen",
        "What would an icon like this likely be for? (1) show wheels, or (2) optionsn",
        "In a racing game, what would this be for? (1) health bar, or (2) fuel tank metern",
        "What would this button likely do? (1) exit or cancel, or (2) mark a spot with an xn"
    };
    switch (msg)
    {
    case WM_CREATE:
        combobox = CreateWindow("ComboBox", 0, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE, 0, 100, 700, 30, hwnd, HMENU(100), 0, 0);
        for (auto line : vec) SendMessage(combobox, CB_ADDSTRING, 0, LPARAM(line.c_str()));
        break;
    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
            DestroyWindow(hwnd);
        break;
    case WM_COMMAND:
        if (HIWORD(wParam) == CBN_SELCHANGE)
            InvalidateRect(hwnd, NULL, TRUE);
        break;
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        int sel = SendMessage(combobox, CB_GETCURSEL, 0, 0);
        if (sel < 0) sel = 0;
        TextOut(hdc, 0, 0, vec[sel].c_str(), vec[sel].size());
        EndPaint(hwnd, &ps);
        break;
    }
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wcx = { 0 };
    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.lpszClassName = "ClassName";
    wcx.lpfnWndProc = WndProc;
    wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    RegisterClassEx(&wcx);
    HWND hwnd = CreateWindowEx(0, wcx.lpszClassName, "G-Learning by James Monk", WS_VISIBLE|WS_OVERLAPPEDWINDOW, 0,0,800,600, NULL, NULL, hInstance, NULL);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}