首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++ Builder DirectX 程式設計入門 (4):DirectDraw 完整實作代碼與表面操作細節

     編輯:VC 教學

主程式碼

#include <vcl.h>
#pragma hdrstop
#include "main.h"

#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {}

// 建立 DD 物件、設定全螢幕 800x600 16bit
void __fastcall TForm1::Button1Click(TObject *Sender) {
    if (!FAILED(DirectDrawCreate(NULL, &lpDD, NULL))) {
        if (!FAILED(lpDD->QueryInterface(IID_IDirectDraw2, (LPVOID*)&lpDD2))) {
            lpDD->Release();
            if (!FAILED(lpDD2->SetCooperativeLevel(Handle,
                DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_NOWINDOWCHANGES))) {
                if (!FAILED(lpDD2->SetDisplayMode(800,600,16,0,0))) {
                    Memo1->Lines->Text += "Create DirectDraw Object OK.\r\n";
                    Button1->Enabled = false; Button2->Enabled = true; return;
                }
            }
        }
    }
    Memo1->Lines->Text += "Create DirectDraw Object Failed.\r\n";
}

// 建立主圖面
void __fastcall TForm1::Button2Click(TObject *Sender) {
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    if (FAILED(lpDD2->CreateSurface(&ddsd, &lpDDPrimary, NULL)))
        Memo1->Lines->Text += "Create Primary Surface Failed.\r\n";
    else {
        Memo1->Lines->Text += "Create Primary Surface OK.\r\n";
        Button2->Enabled = false; Button3->Enabled = true;
    }
}

// 建立 100x100 後台圖面
void __fastcall TForm1::Button3Click(TObject *Sender) {
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
    ddsd.dwHeight = 100; ddsd.dwWidth = 100;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    if (FAILED(lpDD2->CreateSurface(&ddsd, &lpDDOffScreen, NULL)))
        Memo1->Lines->Text += "Create OffScreen Surface Failed.\r\n";
    else {
        Memo1->Lines->Text += "Create OffScreen Surface OK.\r\n";
        Button3->Enabled = false; Button4->Enabled = true;
    }
}

// 關閉視窗釋放介面
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) {
    lpDD2->Release();
}

// 載入 view.bmp 到後台圖面 (100x100)
void __fastcall TForm1::Button4Click(TObject *Sender) {
    HDC hdc, hdcImage; HBITMAP hbm;
    hbm = (HBITMAP)LoadImage(NULL, "view.bmp", IMAGE_BITMAP, 100, 100,
        LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    hdcImage = CreateCompatibleDC(NULL);
    SelectObject(hdcImage, hbm);
    if (FAILED(lpDDOffScreen->GetDC(&hdc)))
        Memo1->Lines->Text += "Get DC of OffScreen Failed.\r\n";
    else {
        if (BitBlt(hdc,0,0,100,100,hdcImage,0,0,SRCCOPY) == FALSE)
            Memo1->Lines->Text += "OffScreen BitBlt Failed.\r\n";
        else {
            Memo1->Lines->Text += "OffScreen BitBlt OK.\r\n";
            Button4->Enabled = false; Button5->Enabled = true;
        }
        lpDDOffScreen->ReleaseDC(hdc);
    }
    if (hdcImage) DeleteDC(hdcImage);
    if (hbm) DeleteObject(hbm);
}

// 載入 view.bmp 到主圖面 (縮放 200x100)
void __fastcall TForm1::Button5Click(TObject *Sender) {
    HDC hdc, hdcImage; HBITMAP hbm;
    hbm = (HBITMAP)LoadImage(NULL, "view.bmp", IMAGE_BITMAP, 200, 100,
        LR_LOADFROMFILE|LR_CREATEDIBSECTION);
    hdcImage = CreateCompatibleDC(NULL);
    SelectObject(hdcImage, hbm);
    if (FAILED(lpDDPrimary->GetDC(&hdc)))
        Memo1->Lines->Text += "Get DC of Primary Failed.\r\n";
    else {
        if (BitBlt(hdc,0,0,200,100,hdcImage,0,0,SRCCOPY) == FALSE)
            Memo1->Lines->Text += "Primary BitBlt Failed.\r\n";
        else {
            Memo1->Lines->Text += "Primary BitBlt OK.\r\n";
            Button5->Enabled = false; Button6->Enabled = true;
        }
        lpDDPrimary->ReleaseDC(hdc);
    }
    if (hdcImage) DeleteDC(hdcImage);
    if (hbm) DeleteObject(hbm);
}

// 後台圖面拷貝至主圖面 (200,0)
void __fastcall TForm1::Button6Click(TObject *Sender) {
    HDC hdcPrimary, hdcOffScreen;
    lpDDPrimary->GetDC(&hdcPrimary);
    lpDDOffScreen->GetDC(&hdcOffScreen);
    BitBlt(hdcPrimary,200,0,100,100,hdcOffScreen,0,0,SRCCOPY);
    lpDDPrimary->ReleaseDC(hdcPrimary);
    lpDDOffScreen->ReleaseDC(hdcOffScreen);
    Memo1->Lines->Text += "OffScreen To Primary OK.\r\n";
    Button6->Enabled = false; Button7->Enabled = true;
}

// 切換 640x480 觸發圖面遺失
void __fastcall TForm1::Button7Click(TObject *Sender) {
    lpDD2->SetDisplayMode(640,480,16,0,0);
    if (lpDDPrimary->IsLost() == DDERR_SURFACELOST &&
        lpDDOffScreen->IsLost() == DDERR_SURFACELOST)
        Memo1->Lines->Text += "Surfaces are Lost.\r\n";
    else
        Memo1->Lines->Text += "Surfaces remain.\r\n";
    Button7->Enabled = false; Button8->Enabled = true;
}

// 恢復顯示模式與圖面
void __fastcall TForm1::Button8Click(TObject *Sender) {
    lpDD2->SetDisplayMode(800,600,16,0,0);
    lpDDPrimary->Restore();
    lpDDOffScreen->Restore();
    Memo1->Lines->Text += "Restore lost Surfaces OK.\r\n";
    Button8->Enabled = false; Button9->Enabled = true;
}

// 重繪所有圖形
void __fastcall TForm1::Button9Click(TObject *Sender) {
    Button4Click(Sender);
    Button5Click(Sender);
    Button6Click(Sender);
}

代碼涵蓋 DD 初始化、主/後台圖面建立、GDI 載入位圖、BitBlt 繪製與縮放、表面拷貝、模式切換導致遺失、恢復與重繪的完整生命週期管理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved