視覺化開發工具雖加速佈局,但固定座標在視窗縮放、解析度變更時會導致 UI 錯位。C++Builder 提供 OnResize 事件、容器控制項(TPanel/TGroupBox)、Windows API GetDeviceCaps 三大機制,實現控制項位置與大小的動態自適應。本文系統說明三種技術與組合策略。
TForm::OnResize 於視窗建立、最大化/最小化/還原、拖曳邊框調整大小時觸發。
void __fastcall TForm1::FormResize(TObject *Sender)
{
int midX = ClientWidth / 2;
Label1->Left = midX - Label1->Width / 2;
Button1->Left = midX - Button1->Width / 2;
}
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 列印佈局。
TPanel/TGroupBox 將功能區塊分組,容器對齊邊距、填滿模式 (Align 屬性:alTop/alClient/alLeft 等) 由 VCL 自動處理。OnResize 中處理特殊對齊(置中、等寬分佈、固定間距)與容器內子項微調。TFlowLayout:流式佈局,自動換行。TGridLayout:網格佈局,固定行列。TGridPanelLayout:比例網格,支援百分比欄寬/列高。傳統 OnResize + 容器 + GetDeviceCaps 三劍客可解決 90% 自適應需求;新專案建議直接使用 VCL 佈局管理器,宣告式佈局更簡潔、支援 High DPI、減少手動計算錯誤。掌握兩套技術,新舊專案皆能游刃有餘。