2012-01-02 2 views
1

Я участвую в программировании на C++. Мы должны запрограммировать textadventure на консоли для окон. Мы получаем очки за реализацию растровых изображений. У меня есть следующий код для отображения растрового изображения. Он работает хорошо, но когда я сворачиваю свое окно, мое растровое изображение исчезает. Где проблема?Растровое изображение исчезает, когда программа сведена к минимуму.

bool DisplayBitmap(char *szBitmap, int PosX = -1, int PosY = -1, bool AutoZoom = false) 
{ 

    HWND hWnd = FindWindow("ConsoleWindowClass",NULL);  // Konsolen-Fenster identifizieren 
    if (!hWnd) return false; 

    HDC hDC = GetDC(hWnd);         // Device Context des Fensters ermitteln 
    if (!hDC) return false; 

    HDC hBitmapDC = CreateCompatibleDC(hDC);    // Device Context für Bitmap bereitstellen 
    if (!hBitmapDC) return false; 

    HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,szBitmap,  // Bild aus Datei laden 
         IMAGE_BITMAP,0,0,LR_LOADFROMFILE); 
    if (!hBitmap) return false; 

    BITMAP bmp; 
    GetObject(hBitmap,sizeof(bmp),&bmp);     // Zeiger auf Bitmap-Objekt anfordern 

    RECT Client; 
    GetClientRect(hWnd, &Client);       // Fenstergröße bestimmen 
    if (PosX == -1) PosX = ((Client.right-Client.left)-bmp.bmWidth)/2; 
    if (PosY == -1) PosY = 250-bmp.bmHeight;    // ggfs. automatisch zentrieren 
    if (PosY < 0) PosY = 0;        // und Zoomfaktor berechnen 
    double ZoomFactor = (Client.right-Client.left-2*PosX)/double(bmp.bmWidth); 

    SelectObject(hBitmapDC,hBitmap);      // Bitmap kopieren (evtl. mit Zoom) 
    if (!AutoZoom)  BitBlt(hDC,PosX,PosY,bmp.bmWidth,bmp.bmHeight,hBitmapDC,0,0,SRCCOPY); 
    else StretchBlt(hDC,PosX,PosY,int(bmp.bmWidth*ZoomFactor),int(bmp.bmHeight*ZoomFactor),hBitmapDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 

    DeleteObject(hBitmap);         // Objekte und Device Contexts wieder freigeben 
    ReleaseDC(hWnd,hBitmapDC); 
    ReleaseDC(hWnd,hDC); 

    return true; 
} 
+1

Вы действительно должны создать свое собственное окно, чтобы показать растровое изображение. Использование консольного окна таким образом можно было бы рассматривать как _rude_, мягко говоря. И могут возникнуть бесчисленные проблемы. – rodrigo

+0

Да, но мы должны сделать это таким образом. Наш профессор дал этот пример, чтобы использовать его в нашей игре. –

+1

Argh! Тогда вы должны изменить профессора. :(Ваша проблема не имеет разумного решения, кроме перерисовки вашего растрового изображения из таймера. Или использовать команду пользователя «перерисовать». – rodrigo

ответ

1

Растровое изображение исчезает, потому что окно консоли перерисовывается при восстановлении, а процедура перекраски ничего не знает о вашем растровом изображении.

Windows перекрашивается довольно часто: каждый раз, когда ваше окно отображается или изменяется или восстанавливается из знакового состояния, окно перекрашивается (ну, может быть, не каждый раз, потому что система может сделать некоторое кеширование ... но все же) , Когда окно должно быть перекрашено, Windows отправляет сообщение WM_PAINT в окно. Это приложение обрабатывает это сообщение и перерисовывает содержимое окна в окне DC. Вот как работают графические приложения. Но если вы используете консоль, вы не можете обрабатывать оконные сообщения - система делает это за вас, и вы не можете изменить процедуру перекраски.

Если вы хотите, чтобы ваше растровое изображение всегда было там, вы должны создать свое собственное окно и обработать сообщение WM_PAINT (или вы можете использовать некоторый предопределенный элемент управления, предназначенный для отображения растровых изображений). Для этого вы должны создать GUI-приложение. Вы не можете сделать это с помощью консольного приложения.

Код, который вы предоставили, является просто взломом, и он не одобрен, чтобы работать так, как вы ожидаете. Когда код выполнен, растровое изображение рисуется. Но как только часть окна будет скрыта за другим окном, изображение будет потеряно, и никто не восстановит его.

Кстати, если ваш профессор дал вам этот пример, возможно, он будет удовлетворен результатом, который он производит. Но никогда не делайте этого в реальной жизни :)

+0

btw я должен сказать, что мы используем afxwin.h , который, кажется, является частью из MFC-приложений. Мы только что узнали C++, поэтому я ничего не знаю об этом. Может быть, здесь есть что-то сделать? –

+0

Консольные приложения все еще являются приложениями Windows, поэтому они могут использовать вызовы WinAPI (вы используете их много в своем коде). Для их использования вам нужны прототипы функций, определенные в «windows.h», поэтому вы должны включать его прямо или косвенно через afxwin.h Также вы можете использовать MFC в консольных приложениях. Но все же в консольном приложении вы не можете контролировать обработку оконные сообщения. –