2012-01-02 22 views
1

私はC++ゲームプログラミングの学生です。ウィンドウのためにコンソール上にテキストアドベンチャーをプログラムする必要があります。 ビットマップの実装のポイントを取得します。 ビットマップを表示する次のコードがあります。それはうまく動作しますが、ウィンドウを最小化するとビットマップが消えます。 どこに問題がありますか?プログラムが最小化されたときにビットマップが消える

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に再描画します。これがGUIアプリケーションの仕組みです。しかし、コンソールを使用する場合、ウィンドウメッセージを処理することはできません。システムがそれを行い、再描画手順を変更することはできません。

ビットマップが常に存在するようにするには、独自のウィンドウを作成し、WM_PAINTメッセージを処理する必要があります(または、ビットマップを表示するために定義されたコントロールを使用することもできます)。これを行うには、GUIアプリケーションを作成する必要があります。コンソールアプリケーションではこれを行うことはできません。

あなたが提供したコードはちょうどハックであり、期待どおりに動作するようにサポートされていません。コードが実行されると、ビットマップが描画されます。しかし、ウィンドウの一部が別のウィンドウを越えて隠れると、イメージは失われ、誰も復元しません。

ところで、もしあなたの教授があなたにこの例を教えたら、おそらく彼はそれが作り出す結果に満足するでしょう。しかし、現実の生活の中でこれは決してしないでください:)

+0

btw私はafxwin.h 部分 –

+0

コンソールアプリケーションはまだWindowsアプリケーションなので、WinAPI呼び出しを使用することができます(コード内で多くのものを使用します)。 )それらを使用するには、 "windows.h"で定義された関数プロトタイプが必要です。したがって、afxwin.hを通して直接的または間接的にそれを含める必要があります。また、コンソールアプリケーションでMFCを使用することもできます。ウィンドウメッセージ。 –

関連する問題