2016-10-16 3 views
0

사용자 입력시 다른 .bmp 이미지가 변경되도록 표시 할 때 문제가 있습니다. 시작 (title.bmp)에서 이미지를 성공적으로 인쇄 할 수 있지만 1 또는 2를 누른 후 (introduction.bmp & start.bmp)를 입력하면 이미지가 변경됩니다. 나는 뭔가를 놓치고 있어야합니다!WinAPI에서 사용자 입력시 C++ 이미지 변경

코드 하단에 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; 
     } 
    } 
+0

Petzold의 [Programming Windows®, Fifth Edition] (https://www.amazon.com/dp/157231995X)와 같은 좋은 프로그래밍 안내서를 읽으십시오. 참을성이 없다면이 자습서 [C++로 Windows 용 프로그램 배우기] (https://msdn.microsoft.com/en-us/library/windows/desktop/ff381399.aspx)를 살펴보십시오. 튜토리얼에서 숙련도를 기대하지 마십시오. – IInspectable

+0

아마도 MinGW를 디버그 모드로 사용하고있을 것입니다. 디버그 보고서 용 콘솔 창을 보여줍니다. 응용 프로그램의 최종 버전은 "릴리스 모드"여야하며 해당 버전에 동봉 된 콘솔 창이 없습니다. –

답변

0
는 정수 값으로 변환하려면 문자열은 다음 그렇지 않으면 API 사용 당신이 다음에서 사용자의 입력을받을 에디트 박스를 사용는 Win32에서 CIN 사용할 수 없습니다

: 당신이

GetDlgItemInt(...); 

을 또한 while 루프에서 GetMessage 만 처리하는 경우에는 dispatchmessage를 루프 외부에서 처리해야합니다. 즉, getmessage가 실패 할 때 (프로그램 끝) 한 번만 처리한다는 것을 의미합니다. 따라서 메시지를 가져 오는 사람이없는 한 결과는 고정 창입니다. 목표물에 도착해라.

솔루션 : While 루프 안에 DispatchMessage합니다

  • 다른 일을 : 당신은 응용 프로그램 종료를하지 않습니다 창을 파괴하는 결과를 GetMessage 함수에 HWND 전달합니다.

는 GetMessage 함수()를 살펴 null 이외의 값을 전달할 때 : link text

귀하의 경우 올바른 일 :

while (GetMessage(&msg, 0, 0, 0) > 0) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

이 * 루프 내에서 이미지를로드하지 않습니다 단지 원하는 시간에로드 :

스타일이 ES_NUMBER 인 편집 상자를 만들고 다른 버튼 이름 (예 : 이미지 변경)을 클릭하면 편집 상자의 내용을 정수로 변환하고, 1 또는 2인지 확인한 다음 값에 따라 이미지를로드하십시오.

  • "콘솔 창이 있습니까?"라는 질문을하기 때문에 "왜 iostream 입력 및 출력 스트림을 win32에서 사용할 수 없습니까?"라는 질문을 할 수 있습니다. while 루프 (메시지 대기 차단)의 역할은 무엇입니까?