TColor 在 VCL 中以 32 位整數儲存顏色資訊,低 24 位分別對應藍、綠、紅三通道(BGR 順序)。Windows API 提供 GetRValue、GetGValue、GetBValue 三個巨集函式,可快速提取各通道亮度(0–255)。本文示範如何利用這三個巨集,即時解析表單背景色的 RGB 分量、調整亮度後重新合成並套用,實現動態變色效果。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// 1. 取得目前表單背景色的三原色亮度
BYTE nRed = GetRValue(Color); // 紅通道 0-255
BYTE nGreen = GetGValue(Color); // 綠通道
BYTE nBlue = GetBValue(Color); // 藍通道
// 2. 任意調整亮度(示範:紅+10、藍-10、綠*1.05)
nRed += 10;
nBlue -= 10;
nGreen = (BYTE)(nGreen * 1.05);
// 3. 合成新顏色並套用
Color = (TColor)RGB(nRed, nGreen, nBlue);
}
GetRValue、GetGValue、GetBValue 在 wingdi.h 中定義為 C 巨集,非真正函式。優點是零呼叫開銷;缺點是不具型別安全——傳入指標、結構體等錯誤型別也不會報錯,編譯器僅做文字替換。
RGB(r,g,b) 將三個 0–255 的位元組合併為 0x00BBGGRR。若傳入值超出範圍(如 300 或 -10),巨集只取低 8 位,等同 value & 0xFF。上例中 nGreen * 1.05 可能超過 255,賦值給 BYTE 時會自動截斷,再經 RGB 合成時再次截斷,雙重保險。
clBtnFace、clWindowText 等)為負數,對應 GetSysColor 索引。Color 為系統色,GetRValue 等巨集會回傳該系統色當下的 RGB 值,而非索引本身。Color 設為 clBlue、clNavy 等非系統色,確保直接操作 RGB 值。void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static int phase = 0;
BYTE r = GetRValue(Color);
BYTE g = GetGValue(Color);
BYTE b = GetBValue(Color);
switch (phase % 3)
{
case 0: r = (r + 5) % 256; break;
case 1: g = (g + 7) % 256; break;
case 2: b = (b + 11) % 256; break;
}
Color = (TColor)RGB(r, g, b);
phase++;
}
搭配 TTimer 即可實現流暢的背景色漸變動畫,適合啟動畫面、狀態指示等場景。
| 誤區 | 正確觀念 |
|---|---|
| 以為 GetRValue 回傳 0–1 的浮點數 | 回傳 0–255 的整數(BYTE) |
| 直接對 TColor 做位元運算 | 建議用 GetRValue/G/BValue 讀取,RGB 合成,可讀性高且跨平台相容 |
| 忽略系統色與 RGB 色的差異 | 系統色需先 GetSysColor 轉換為 RGB 再操作 |
掌握 GetRValue/GetGValue/GetBValue 與 RGB 的配合使用,即可在 C++Builder 中靈活操控色彩,為應用程式增添動態視覺效果。