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

C++Builder TScreen 類詳解:螢幕狀態感知、多視窗管理、字體光標資源與高 DPI 適配實戰

     編輯:關於C++

C++Builder TScreen 類詳解:螢幕狀態感知、多視窗管理、字體光標資源與高 DPI 適配實戰

TScreen 代表應用程式運行環境的顯示裝置抽象,全域單例 Screen(定義於 Forms.hpp)提供螢幕幾何屬性、視窗/數據模組枚舉、系統字體/光標/輸入法清單、焦點追蹤事件等能力。本文系統講解核心屬性、多視窗協調模式、自定義光標註冊、高 DPI 適配策略與常見陷阱。

類層次與單例

TObject
  └── TPersistent
        └── TComponent
              └── TScreen  // 非視覺,全域單例 Screen

核心屬性分類速查

類別屬性類型說明
幾何屬性Width/Heightint螢幕像素寬高(虛擬桌面包含所有監視器)
PixelsPerInchint垂直 DPI(通常 96/120/144/192),水平需自行查詢
WorkAreaWidth/Heightint工作區(扣除任務列)尺寸,VCL 內部計算
視窗枚舉FormCount/Forms[]int / TForm*當前顯示的 TForm 列表
CustomFormCount/CustomForms[]int / TCustomForm*含 TForm、TPropertyPage 等
DataModuleCount/DataModules[]int / TDataModule*已實例化數據模組
ActiveForm/ActiveControlTForm* / TWinControl*當前焦點視窗/控件(只讀)
字體/光標/輸入法FontsTStrings*系統安裝字體名稱列表
Cursors[int Index]HICON光標句柄陣列(含內建 + 自定義)
Imes/DefaultIme/DefaultKbLayoutTStrings* / AnsiString / HKL輸入法編輯器清單與預設狀態
IconFontTFont*圖標標籤字體(Shell 介面一致性)

焦點追蹤事件

事件觸發時機典型用途
OnActiveControlChange焦點在控件間移動(含跨視窗)工具欄按鈕狀態同步、狀態列上下文更新
OnActiveFormChange活動視窗切換MDI 子視窗菜單合併、視窗特定工具欄顯隱

事件順序:跨視窗焦點移動 → OnActiveFormChange → OnActiveControlChange。

自定義光標註冊完整流程

  1. 資源編輯器建立 .cur/.ani,資源 ID 如 CUR_MYCUSTOM。
  2. 定義常數避開系統值(系統值 ≤ 0):
    const int crMyCustom = 100;
  3. 載入並註冊:
    HICON hCur = LoadCursor(HInstance, MAKEINTRESOURCE(CUR_MYCUSTOM));
    Screen->Cursors[crMyCustom] = hCur;  // 索引即常數值
  4. 使用:Control->Cursor = crMyCustom; 或 Screen->Cursor = crMyCustom;(全域)。
  5. 無需銷毀:VCL 應用結束時自動 DestroyCursor。

高 DPI 適配:PixelsPerInch 與縮放因子

// 獲取主監視器 DPI(Win10 1703+)
UINT dpiX, dpiY;
GetDpiForMonitor(MonitorFromWindow(Application->Handle, MONITOR_DEFAULTTOPRIMARY),
                 MDT_EFFECTIVE_DPI, &dpiX, &dpiY);

// 邏輯像素 → 物理像素
int PhysicalX = MulDiv(LogicalX, dpiX, 96);
int PhysicalY = MulDiv(LogicalY, dpiY, 96);

// 字體大小調整(邏輯點數 → 像素)
int PixelHeight = -MulDiv(PointSize, dpiY, 72);  // LOGFONT lfHeight
Font->Height = PixelHeight;  // 負值表字符高度

關鍵設定:
- Application->Scaled = true(VCL 自動縮放控件)。
- Manifest dpiAware=PerMonitorV2(Win10 1703+)。
- Screen->PixelsPerInch 僅反映主監視器垂直 DPI,多監視器異構 DPI 需自行查詢。

多視窗協調實用模式

// 遍歷所有視窗關閉(除主視窗)
for (int i = Screen->CustomFormCount - 1; i >= 0; --i) {
    TCustomForm* f = Screen->CustomForms[i];
    if (f != Application->MainForm) f->Close();
}

// 尋找特定類型視窗
TMyForm* frm = nullptr;
for (int i = 0; i < Screen->FormCount; ++i)
    if (dynamic_cast(Screen->Forms[i])) { frm = (TMyForm*)Screen->Forms[i]; break; }

// 全域焦點控件安全檢查
if (Screen->ActiveControl && Screen->ActiveControl->HandleAllocated())
    Screen->ActiveControl->SetFocus();

常見陷阱

現象原因對策
Width/Height 不等於主監視器解析度虛擬桌面跨多監視器用 GetMonitorInfo 獲取單監視器矩形
Fonts 列表缺少剛安裝字體字體快取未刷新呼叫 EnumFontFamiliesEx 重新枚舉或重啟應用
自定義光標不顯示資源類型錯誤(用 BITMAP 而非 CURSOR)資源編輯器確認類型為 CURSOR/ANICURSOR
OnActiveFormChange 重複觸發焦點在同視窗內控件移動也觸發事件內比較 Screen->ActiveForm != lastForm
高 DPI 下自繪控件模糊未處理 PixelsPerInch 變化繼承 TWinControl 覆寫 ChangeScale 或用 Scaled 屬性

TScreen 是 VCL 感知「顯示環境」的唯一入口,掌握其幾何查詢、資源枚舉、焦點事件與 DPI 適配模式,即能構建在單/多監視器、標準/高 DPI、不同語系環境下均表現一致的專業桌面應用。

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