首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

C++Builder 控制項自適應佈局:OnResize、容器控制項與螢幕解析度偵測

     編輯:更多程式設計知識

視覺化開發工具雖加速佈局,但固定座標在視窗縮放、解析度變更時會導致 UI 錯位。C++Builder 提供 OnResize 事件、容器控制項(TPanel/TGroupBox)、Windows API GetDeviceCaps 三大機制,實現控制項位置與大小的動態自適應。本文系統說明三種技術與組合策略。

技術一:OnResize 事件動態重新定位

TForm::OnResize 於視窗建立、最大化/最小化/還原、拖曳邊框調整大小時觸發。

基礎範例:單一控制項置中


void __fastcall TForm1::FormResize(TObject *Sender)
{
    int midX = ClientWidth / 2;
    Label1->Left = midX - Label1->Width / 2;
    Button1->Left = midX - Button1->Width / 2;
}

進階:遍歷 Controls 陣列批次處理


void __fastcall TForm1::FormResize(TObject *Sender)
{
    int midX = ClientWidth / 2;
    for (int i = 0; i < ControlCount; ++i) {
        TControl *ctrl = Controls[i];
        ctrl->Left = midX - ctrl->Width / 2; // 全部水平置中
    }
}

限制:Controls 僅包含表單**直接子控制項**,容器內的子控制項不在其中。

技術二:容器控制項分組管理

使用 TPanel、TGroupBox、TScrollBox 等容器,將相關控制項分組,對容器定位即帶動內部群組。

容器內子控制項同步置中


void __fastcall TForm1::FormResize(TObject *Sender)
{
    int midX = ClientWidth / 2;
    for (int i = 0; i < ControlCount; ++i) {
        TControl *ctrl = Controls[i];
        ctrl->Left = midX - ctrl->Width / 2; // 表單層級置中

        if (ctrl == GroupBox1) { // 針對特定容器處理內部子項
            int subMidX = GroupBox1->Width / 2;
            for (int j = 0; j < GroupBox1->ControlCount; ++j) {
                TControl *subCtrl = GroupBox1->Controls[j];
                subCtrl->Left = subMidX - subCtrl->Width / 2;
            }
        }
    }
}

關鍵:每個容器擁有獨立 Controls 陣列與 ControlCount,遞迴處理即可支援任意巢狀深度。

技術三:多解析度自適應佈局

使用 GetDeviceCaps 取得螢幕實際解析度,依比例縮放字體、控制項大小與間距。

取得螢幕解析度


// 專案原始碼 (.cpp) 或表單 OnCreate 中
HDC hdc = GetDC(NULL);
int screenW = GetDeviceCaps(hdc, HORZRES); // 水平像素
int screenH = GetDeviceCaps(hdc, VERTRES); // 垂直像素
ReleaseDC(NULL, hdc);

// 定義基準解析度 (設計時)
const int BaseW = 1024, BaseH = 768;
double scaleX = (double)screenW / BaseW;
double scaleY = (double)screenH / BaseH;

依比例縮放表單與字體


void __fastcall TForm1::ApplyScale(double sx, double sy)
{
    // 縮放表單大小
    Width = (int)(BaseFormWidth * sx);
    Height = (int)(BaseFormHeight * sy);
    // 縮放字體
    Font->Size = (int)(BaseFontSize * min(sx, sy));
    // 觸發 OnResize 重新定位控制項
    // 注意:縮放 Font 會影響文字寬度,置中邏輯自動適應
}

列印預覽同樣適用

GetDeviceCaps(hdc, HORZSIZE)/VERTSIZE 取得實體尺寸 (mm),結合 LOGPIXELSX/Y 計算列印解析度,實現 WYSIWYG 列印佈局。

組合策略:三層自適應架構

  1. 解析度層:啟動時偵測螢幕解析度,計算全域縮放比例,套用至表單尺寸與基準字體。
  2. 容器層:使用 TPanel/TGroupBox 將功能區塊分組,容器對齊邊距、填滿模式 (Align 屬性:alTop/alClient/alLeft 等) 由 VCL 自動處理。
  3. 微調層:OnResize 中處理特殊對齊(置中、等寬分佈、固定間距)與容器內子項微調。

現代替代方案:VCL 佈局管理器 (C++Builder 10.4+)

  • TFlowLayout:流式佈局,自動換行。
  • TGridLayout:網格佈局,固定行列。
  • TGridPanelLayout:比例網格,支援百分比欄寬/列高。
  • 將控制項放入佈局管理器,無需撰寫 OnResize 代碼,自動處理 DPI 感知、高解析度縮放。

結語

傳統 OnResize + 容器 + GetDeviceCaps 三劍客可解決 90% 自適應需求;新專案建議直接使用 VCL 佈局管理器,宣告式佈局更簡潔、支援 High DPI、減少手動計算錯誤。掌握兩套技術,新舊專案皆能游刃有餘。

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