c++在WinAPI中根据用户输入改变图像
C++ changing image on user input in WinAPI
我在获得我的。bmp图像显示更改为另一个用户输入的问题。图像可以在开始时(title.bmp
)成功打印,但应该在按1或2后按enter(到introduction.bmp
&start.bmp
)。我一定是错过了什么!
发生这种情况的地方是在while (running == 1) {
代码的底部,所以跳到那里。我使用loadImage("title.bmp");
来打印我的图像(当然我适当地更改了文件名),cin >> menuSelection;
暂停程序并等待,直到用户按下一或两个然后输入。
我已经搜索了很多,很多关于如何在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;
//Defining the [global] variables that will be used throughout the program
int running = 1;
int menuSelection = 0;
int userInput;
int userInputDummy;
int intPointer;
//Starter variables used in creating a window and printing images. These are global.
HDC imageDC; // the DC to hold our image
HBITMAP imageBmp; // the actual bitmap which contains the image (will be put in the DC)
HBITMAP imageBmpOld; // the DC's old bitmap (for cleanup)
const int screenSize_X = 640;
const int screenSize_Y = 480;
//Functions! Sections of code to re-used in the program
// Function to load the image into our DC so we can draw it to the screen
void loadImage(const char* pathname)
{
imageDC = CreateCompatibleDC(NULL); // create an offscreen DC
imageBmp = (HBITMAP)LoadImageA( // load the bitmap from a file
NULL, // not loading from a module, so this is NULL
pathname, // the path we're loading from
IMAGE_BITMAP, // we are loading a bitmap
0, 0, // don't need to specify width/height
LR_DEFAULTSIZE | LR_LOADFROMFILE// use the default bitmap size (whatever the file is), and load it from a file
);
imageBmpOld = (HBITMAP)SelectObject(imageDC, imageBmp); // put the loaded image into our DC
}
// Function to clean up
void cleanUpImage()
{
SelectObject(imageDC, imageBmpOld); // put the old bmp back in our DC
DeleteObject(imageBmp); // delete the bmp we loaded
DeleteDC(imageDC); // delete the DC we created
}
// The function to draw our image to the display (the given DC is the screen DC)
void drawImage(HDC screen)
{
BitBlt(
screen, // tell it we want to draw to the screen
0, 0, // as position 0,0 (upper-left corner)
screenSize_X, // width of the rect to draw
screenSize_Y, // height of the rect
imageDC, // the DC to get the rect from (our image DC)
0, 0, // take it from position 0,0 in the image DC
SRCCOPY // tell it to do a pixel-by-pixel copy
);
}
// A callback to handle Windows messages as they happen
LRESULT CALLBACK wndProc(HWND wnd, UINT msg, WPARAM w, LPARAM l)
{
// what kind of message is this?
switch (msg)
{
// we are interested in WM_PAINT, as that is how we draw
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC screen = BeginPaint(wnd, &ps); // Get the screen DC
drawImage(screen); // draw our image to our screen DC
EndPaint(wnd, &ps); // clean up
}break;
// we are also interested in the WM_DESTROY message, as that lets us know when to close the window
case WM_DESTROY:
PostQuitMessage(0);
break;
}
// for everything else, let the default window message handler do its thing
return DefWindowProc(wnd, msg, w, l);
}
// A function to create the window and get it set up
HWND createWindow(HINSTANCE inst)
{
WNDCLASSEX wc = { 0 }; // create a WNDCLASSEX struct and zero it
wc.cbSize = sizeof(WNDCLASSEX); // tell windows the size of this struct
wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); // tell it to use the normal arrow cursor for this window
wc.hInstance = inst; // give it our program instance
wc.lpfnWndProc = wndProc; // tell it to use our wndProc function to handle messages
wc.lpszClassName = TEXT("DisplayImage"); // give this window class a name.
RegisterClassEx(&wc); // register our window class with Windows
// the style of the window we want... we want a normal window but do not want it resizable.
int style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; // normal overlapped window with a caption and a system menu (the X to close)
// Figure out how big we need to make the window so that the CLIENT area (the part we will be drawing to) is
// the desired size
RECT rc = { 0,0,screenSize_X,screenSize_Y }; // desired rect
AdjustWindowRect(&rc, style, FALSE); // adjust the rect with the given style, FALSE because there is no menu
return CreateWindow( // create the window
TEXT("DisplayImage"), // the name of the window class to use for this window (the one we just registered)
TEXT("Display an Image"), // the text to appear on the title of the window
style | WS_VISIBLE, // the style of this window (OR it with WS_VISIBLE so it actually becomes visible immediately)
100, 100, // create it at position 100,100
rc.right - rc.left, // width of the window we want
rc.bottom - rc.top, // height of the window
NULL, NULL, // no parent window, no menu
inst, // our program instance
NULL); // no extra parameter
}
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// _________________________________________________________________________________________
// The actual entry point for the program!
// This is Windows' version of the 'main' function:
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show)
{
// load our image
loadImage("title.bmp");
// create our window
HWND wnd = createWindow(inst);
// Do the message pump! keep polling for messages (and respond to them)
// until the user closes the window.
MSG msg;
while (GetMessage(&msg, wnd, 0, 0)) // while we are getting non-WM_QUIT messages...
TranslateMessage(&msg); // translate them
DispatchMessage(&msg); // and dispatch them (our wndProc will process them)
{
while (running == 1) {
//Welcoming the user to the program, and asking them what they want to do (starts functions)
cin >> menuSelection;
//Selecting the introduction option
if (menuSelection == 1) {
loadImage("introduction.bmp");
cin >> userInputDummy;
menuSelection = 0;
}
//Selecting the start option
else if (menuSelection == 2) {
loadImage("start");
cin >> userInputDummy;
menuSelection = 0;
}
//Selecting the exit option
else if (menuSelection == 3) {
menuSelection = 0;
running = 0;
}
}
// once the user quits....
cleanUpImage();
return 0;
return EXIT_SUCCESS;
}
}
你不能在win32中使用cin,使用编辑框然后从它作为字符串获取用户的输入,然后如果你想将其转换为整数值,否则使用API:
GetDlgItemInt(...);
你也只在while-loop中处理GetMessage,而你只在循环外处理dispatchmessage,这意味着你只处理一次,当GetMessage失败时(程序结束),所以结果是一个冻结窗口,只要没有人从GetMessage获取消息到目标窗口。
解决方案:在while循环中使用DispatchMessage:
- 另一件事:你传递hwnd给getmessage,结果销毁窗口不会使应用程序退出。
看一下GetMessage()传递非空值时的情况:链接文本
正确的事情在你的情况:
while (GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
*不要在循环内加载图像,只在需要的时间加载:
创建一个样式为ES_NUMBER的编辑框和另一个按钮名称,例如,更改图像,当单击时,将编辑框的内容转换为整数,检查它是1还是2,然后根据值加载图像。
- 你可能会问"为什么我不能在win32中使用iostream输入和输出流",因为我问你"控制台窗口在哪里?"如果它在这里,while-loop(阻塞等待消息)的作用是什么?
相关文章:
- C++如何通过用户输入删除列表元素
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 如何只允许用户输入正整数
- C++如何计算用户输入的数字中的偶数位数
- 通过for循环使用用户输入填充列表
- 在C++中,我如何接受不同于同一行的用户输入
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 显示基于用户输入的整数的字符
- 根据用户输入用字母填充矢量,并将"开始"和"结束"放在四肢
- 我试图制作一个程序,要求用户输入问题和答案,但程序循环不正确
- 打印时有二叉树问题.用户输入不打印任何内容
- C ++奇怪的数组由用户输入
- 如何允许大写和小写用户输入?
- C++读取用户输入而不按回车键(Mac OS X),与Turbo Pascal中的读取键相同
- 如何存储用户输入的所有数据,然后在他们想要查看所有数据时显示它们
- 如何使用用户输入变量制作二维数组?
- 用户输入字符串的文件附加问题..C++
- 遇到此问题时遇到困难:允许用户输入数组的值并使用 for,而循环也输出输入的最大数字
- 如何使用递归循环我的代码(当用户输入无效输入时,它会再次提示他们)?