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

BCB 實現全螢幕 OpenGL:WS_POPUP 視窗樣式與解析度切換

     編輯:VC 教學

核心原理

全螢幕 OpenGL 本質是**無邊框、無標題、覆蓋全螢幕的彈出式視窗** + **切換顯示解析度**。只需在視窗類別的 CreateParams 中修改樣式並設定尺寸即可。

一、視窗樣式修改:WS_POPUP


void __fastcall TMyGLForm::CreateParams(TCreateParams &Params) {
    TForm::CreateParams(Params);
    Params.Style = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    // WS_POPUP: 無標題列、無邊框、不在工作列顯示
    // WS_CLIPCHILDREN/WS_CLIPSIBLINGS: 防止子視窗/同層視窗繪圖衝突,OpenGL 必備
}

二、解析度切換與視窗尺寸


void __fastcall TMyGLForm::CreateParams(TCreateParams &Params) {
    TForm::CreateParams(Params);
    Params.Style = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

    ChangeResolution(800, 600);        // 切換顯示模式
    Params.Width  = 800;
    Params.Height = 600;
    Params.X = Params.Y = 0;           // 左上角對齊螢幕原點
}

三、ChangeResolution 完整實作


bool ChangeResolution(DWORD w, DWORD h) {
    DEVMODE dm = {0};
    dm.dmSize = sizeof(DEVMODE);
    LONG i = 0, modeSwitch;

    // 1. 列舉顯示模式,尋找符合寬高且 16 位元色深的模式
    do {
        modeSwitch = EnumDisplaySettings(NULL, i++, &dm);
    } while (modeSwitch &&
             (dm.dmBitsPerPel != 16 || dm.dmPelsWidth != w || dm.dmPelsHeight != h));

    if (!modeSwitch) return false; // 找不到支援模式

    // 2. 嘗試套用
    modeSwitch = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
    if (modeSwitch != DISP_CHANGE_SUCCESSFUL) {
        // 3. 兼容舊驅動:嘗試不指定刷新率
        dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
        dm.dmBitsPerPel = 16;
        dm.dmPelsWidth = w;
        dm.dmPelsHeight = h;
        modeSwitch = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
    }
    return modeSwitch == DISP_CHANGE_SUCCESSFUL;
}

關鍵點:

  • CDS_FULLSCREEN:標記為全螢幕模式切換,離開程式自動恢復原解析度。
  • 優先嘗試完整 DEVMODE(含刷新率),失敗則退回最小欄位集合。
  • 色深固定 16 位(高相容),現代可改 32 位(dmBitsPerPel = 32)。

四、恢復解析度:視窗關閉時


void __fastcall TMyGLForm::FormClose(TObject *Sender, TCloseAction &Action) {
    ChangeDisplaySettings(NULL, 0); // 還原系統預設模式
}

五、工作列遮蓋問題

若工作列設定「永遠在最上層」,全螢幕視窗底部會露出一條白線。解決:

  • 視窗設定 FormStyle = fsStayOnTop(Always On Top),覆蓋工作列。
  • 或程式啟動時呼叫 SetWindowPos(Handle, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE)。

六、完整最小範例專案結構

  1. 新建 VCL Forms Application。
  2. 主視窗類別繼承 TForm,覆寫 CreateParams、FormClose。
  3. 在 FormCreate 初始化 OpenGL RC(wglCreateContext、wglMakeCurrent、設定投影矩陣)。
  4. 在 FormPaint 或計時器中渲染 OpenGL 場景,SwapBuffers。
  5. 編譯執行,即進入全螢幕 OpenGL 模式。

七、現代替代方案

  • GLFW / SDL2:跨平台、自動處理全螢幕/視窗切換、輸入/音訊,建議新專案直接使用。
  • DirectX 11/12 SwapChain:SetFullscreenState(TRUE) 原生全螢幕,效能最佳。
  • Borderless Windowed:視窗模式但尺寸等於桌面解析度,切換快、相容性好,現代遊戲主流選擇。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved