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

C++ Builder DirectX 程式設計實戰(二):裝置列舉、建立 DD 物件與顯示模式設定完整碼

     編輯:關於C++

前言

本文提供 dx1 範例的完整 main.h、main.cpp 原始碼,詳細展示從裝置列舉、建立 DirectDraw 物件、取得 IDirectDraw2 介面、設定協作等級、列舉顯示模式到設定顯示模式的完整程式碼實作。

一、主視窗類別宣告

class TForm1 : public TForm {
__published:
    // 元件宣告:ComboBox1(裝置), ComboBox2(顯示模式),
    // Edit1(狀態), CheckBox1-6(協作旗標), Button1-6(步驟按鈕)
private:
    LPDIRECTDRAW  FAR lpDD;
    LPDIRECTDRAW2 FAR lpDD2;
    LPGUID        FAR lpDevices[10];      // 列舉裝置 GUID
    struct { DWORD Width, Height, Depth, Rate; } DisplayMode[100];
public:
    __fastcall TForm1(TComponent* Owner);
};

二、裝置列舉回呼函數

BOOL WINAPI EnumDeviceCallBack(GUID FAR* lpGUID, LPSTR lpDevice,
    LPSTR lpDeviceName, LPVOID lpContext) {
    static char i = 0;
    lpDevices[i] = lpGUID; // 保存 GUID 指標
    Form1->ComboBox1->Items->Add(
        AnsiString(lpDevice) + "--" + AnsiString(lpDeviceName));
    return (i++ < 10) ? DDENUMRET_OK : DDENUMRET_CANCEL;
}

按鈕 1:列舉裝置

void __fastcall TForm1::Button1Click(TObject *Sender) {
    ComboBox1->Clear();
    if (FAILED(DirectDrawEnumerate(EnumDeviceCallBack, NULL)))
        Edit1->Text = "Enumerate Devices failed!";
    else
        Edit1->Text = "Enumerate Devices OK!";
    ComboBox1->ItemIndex = 0;
    Button1->Enabled = false; Button2->Enabled = true;
}

三、建立 DirectDraw 物件

void __fastcall TForm1::Button2Click(TObject *Sender) {
    LPGUID FAR lpD = lpDevices[ComboBox1->ItemIndex];
    if (FAILED(DirectDrawCreate(lpD, &lpDD, NULL)))
        Edit1->Text = "DirectDraw Create failed!";
    else {
        Edit1->Text = "DirectDraw Create OK!";
        ComboBox1->Enabled = false;
        Button2->Enabled = false; Button3->Enabled = true;
    }
}

四、取得 IDirectDraw2 介面

void __fastcall TForm1::Button3Click(TObject *Sender) {
    if (FAILED(lpDD->QueryInterface(IID_IDirectDraw2,
        (LPVOID*)&lpDD2)))
        Edit1->Text = "Get IDirectDraw2 Interface Failed!";
    else {
        Edit1->Text = "Get IDirectDraw2 Interface OK!";
        lpDD->Release(); // 釋放舊介面
        Button3->Enabled = false; Button4->Enabled = true;
    }
}

五、設定協作等級

void __fastcall TForm1::Button4Click(TObject *Sender) {
    DWORD dwFlags = 0;
    if (CheckBox1->Checked) dwFlags |= DDSCL_ALLOWMODEX;
    if (CheckBox2->Checked) dwFlags |= DDSCL_ALLOWREBOOT;
    if (CheckBox3->Checked) dwFlags |= DDSCL_EXCLUSIVE;
    if (CheckBox4->Checked) dwFlags |= DDSCL_FULLSCREEN;
    if (CheckBox5->Checked) dwFlags |= DDSCL_NORMAL;
    if (CheckBox6->Checked) dwFlags |= DDSCL_NOWINDOWCHANGES;

    if (FAILED(lpDD2->SetCooperativeLevel(Handle, dwFlags)))
        Edit1->Text = "Set cooperative level Failed!";
    else {
        Edit1->Text = "Set cooperative level OK!";
        GroupBox2->Enabled = false;
        Button4->Enabled = false; Button5->Enabled = true;
    }
}

預設旗標:DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_NOWINDOWCHANGES

六、列舉顯示模式

BOOL WINAPI EnumDisplayModesCallBack(LPDDSURFACEDESC lpDesc,
    LPVOID lpContext) {
    static int i = 0;
    char buff[256];
    wsprintf(buff, "%dx%dx%dx%d",
        lpDesc->dwWidth, lpDesc->dwHeight,
        lpDesc->ddpfPixelFormat.dwRGBBitCount,
        lpDesc->dwRefreshRate);
    Form1->ComboBox2->Items->Add(buff);
    DisplayMode[i].Width  = lpDesc->dwWidth;
    DisplayMode[i].Height = lpDesc->dwHeight;
    DisplayMode[i].Depth  = lpDesc->ddpfPixelFormat.dwRGBBitCount;
    DisplayMode[i].Rate   = lpDesc->dwRefreshRate;
    return (i++ < 100) ? DDENUMRET_OK : DDENUMRET_CANCEL;
}

按鈕 5:列舉模式

void __fastcall TForm1::Button5Click(TObject *Sender) {
    ComboBox2->Clear();
    if (FAILED(lpDD2->EnumDisplayModes(DDEDM_STANDARDVGAMODES,
        NULL, NULL, (LPDDENUMMODESCALLBACK)EnumDisplayModesCallBack)))
        Edit1->Text = "Enumerate Display Modes failed!";
    else {
        Edit1->Text = "Enumerate Display Modes OK!";
        ComboBox2->ItemIndex = 0;
        Button5->Enabled = false; Button6->Enabled = true;
    }
}

七、設定顯示模式

void __fastcall TForm1::Button6Click(TObject *Sender) {
    if (ComboBox2->ItemIndex < 0) {
        ShowMessage("請先選擇顯示方式"); return;
    }
    if (FAILED(lpDD2->SetDisplayMode(
        DisplayMode[ComboBox2->ItemIndex].Width,
        DisplayMode[ComboBox2->ItemIndex].Height,
        DisplayMode[ComboBox2->ItemIndex].Depth,
        DisplayMode[ComboBox2->ItemIndex].Rate, 0)))
        Edit1->Text = "Set DisplayMode failed!";
}

八、程式結束釋放資源

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) {
    if (lpDD2) lpDD2->Release();
}

重點備註

  • 回呼函數不能是類別成員函數,必須是全域或靜態函數。
  • lpDevices、DisplayMode 為靜態陣列,實際專案建議動態配置。
  • IDirectDraw2::SetDisplayMode 比 IDirectDraw 多支援 dwRefreshRate、dwFlags。
  • 專案需設定 Include/Library Path 指向 DirectX SDK。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved