2016-08-18 23 views
1

在一个基本程序中,我需要知道如何使文本显示小部件和图像显示可以根据命令变为不同的字符串和图像。这些将显示在基本的GUI上。在C++中打印文本和图像(WinAPI或QT)

任何特定的帮助将非常感激,因为我一直坚持超过10周!在这里询问是我的最后一招。

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

这是我有史以来第一个在C++中完成的项目,只知道基础知识(我的有限知识的全部范围让我无需帮助即可完成该控制台命令窗口程序)。

我第一次使用WinAPI,因为它与我的电脑在Microsoft Visual Studio中一起使用,并且已经回答了其他类似问题,尝试了许多不同的建议,但总是有两个问题之一; 1.他们提供的代码有很多错误,其中大部分读取“_未定义”或未正确导入,或者2.成功创建基本文本,但未指定如何在创建后更改它(我已经迄今没有成功的图像打印)。我已经尝试了3个来自cplusplus.com的问题/答案和3个来自堆栈溢出的问题(链接将在下面),并且他们都有这2个问题是由于我缺乏C++错误修复技能而创建的。

使用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) punishments\n", 
    "What does 'Game Over' mean? (1) your session has ended, or (2) the game is no longer playable\n", 
    "What would an icon like this likely be for? (1) show wheels, or (2) options\n", 
    "In a racing game, what would this be for? (1) health bar, or (2) fuel tank meter\n", 
    "What would this button likely do? (1) exit or cancel, or (2) mark a spot with an x\n" }; 

//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. \n\n\ 
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.\n\n\ 
Press any number key followed by enter to return to the main menu.\n\n"); 
    cin >> userInputDummy; 
    menuSelection = 0; 
} 

void start() { 
    printf("\nThe questions will now start, good luck!\n\n"); 
    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 %d\n\n", questionTextPicked, questionRandomised, questionImagePicked); 

     //answering questions should be here 
     stringPointer = questionText[questionTextPicked]; 
     intPointer = questionAnswer[questionImagePicked]; 

     printf("answer is %d\n\n", intPointer); 
     printf("%s\n", stringPointer, intPointer); 
     printf("answer is %d\n\n", intPointer); 
     cin >> userInput; 

     if (userInput == questionAnswer[questionImagePicked]) { 
      printf("\nCorrect!\n\n"); 
      score++; 
     } 
     else { 
      printf("\nIncorrect answer.\n\n"); 
     } 
     questionsLeft--; 

     if (questionsLeft > 0) { 
      printf("%d questions to go!\n\n", questionsLeft); 
     } 

     if (questionsLeft == 0) { 
      printf("All questions have been answered, you scored %d/5.\n\nReturning you to the main menu\n\n", 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: Instructions\n2: Start\n3: Exit\n\n"); 
      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] == '\0') 
      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

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

+0

那么,你问的是如何改变Win32中的文本内容,还是你问别的东西?我真的不明白你在寻求什么帮助。 – Rakete1111

+0

如果可能,我想知道如何更改WinAPI中的文本内容,一旦其他内容已经打印完毕,一旦出现问题,我需要帮助才能显示图像(在文本下方,而不是替换它),这也可以被替换。 – Breadatarian

回答

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

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

而且,在WNDCLASSEX WindowClass;声明中,您错过了初始化hInstance,所以代码将无处可用。在C++ 14中,您可以这样做

WNDCLASSEX WindowClass = {0} 

这会将所有成员初始化为零。尝试在堆栈中声明数据时始终执行此操作。还要避免将随机代码放入消息循环中。

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

上面的头文件用于C输入/输出,C++输入/输出和WinAPI。通常你并不需要他们全部。选一个。

LPSTR TextArray[] = { 
    "Hello World" 
}; 

上面是一个字符数组,或者只是“文本”。如果您访问TextArray[0]它给你的性格'H'

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

上面的代码是的strlen等同。你的代码遍布全球。您拥有C++ 14类,如std::string,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) punishments\n", 
     "What does 'Game Over' mean? (1) your session has ended, or (2) the game is no longer playable\n", 
     "What would an icon like this likely be for? (1) show wheels, or (2) options\n", 
     "In a racing game, what would this be for? (1) health bar, or (2) fuel tank meter\n", 
     "What would this button likely do? (1) exit or cancel, or (2) mark a spot with an x\n" 
    }; 

    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; 
} 
+0

顺便说一句,为了使事情更清楚,在'WM_PAINT'我应该把'std :: string text = vec [sel]'然后你用TextOut(hdc,0,0,text.c_str ),text.size())'。看到这个[示例](http://stackoverflow.com/documentation/c%2b%2b/488/stdstring/2148/tokenize#t=201608181828311312361)解释'std :: vector'和'std :: string' –