VCL 標準 TCheckBox 勾選時顯示核取記號 (✓),若需顯示叉號 (×) 或其他自訂樣式,需繼承 TCustomControl 完全自繪。本文提供完整的 TXCheckBox 元件原始碼,支援三態 (未選/選取/灰態)、自訂勾選顏色、鍵盤滑鼠互動、焦點虛線框等完整功能。
class TXCheckBox : public TCustomControl {
private:
bool FDown; // 按下狀態
TCheckBoxState FState; // cbUnchecked/cbChecked/cbGrayed
bool FFocused; // 焦點狀態
TColor FCheckColor; // 勾選符號顏色
// ... 事件處理函數宣告 ...
public:
__fastcall TXCheckBox(TComponent* AOwner);
// ... 屬性存取函數 ...
__published:
__property TCaption Caption = {read=GetCaption, write=SetCaption};
__property TColor CheckColor = {read=FCheckColor, write=SetCheckColor, default=clBlack};
__property bool Checked = {read=GetChecked, write=SetChecked, default=false};
__property bool Down = {read=FDown, write=SetDown, default=false};
__property TCheckBoxState State = {read=FState, write=SetState, default=cbUnchecked};
// ... 標準事件屬性 OnClick, OnMouseDown 等 ...
};
void __fastcall TXCheckBox::Paint() {
const int BW = 12; // 方框寬高
int BL=1, BT=(Height/2)-(BW/2), BR=BW+1, BB=BT+BW;
TRect Rect;
Canvas->Font = Font;
// 繪製 3D 邊框方框
Canvas->Brush->Color = FDown ? clBtnFace : clWhite;
Canvas->Pen->Width = 1; Canvas->Pen->Color = clBtnFace;
Canvas->Rectangle(BL, BT, BR, BB);
// 陰影與高光邊框 (略,參考完整碼)
// 繪製 Caption 文字
int TX = BR + 5;
int TY = (Height/2) + (Canvas->Font->Height/2) + 1;
Canvas->TextOut(TX, TY, Caption);
// 根據 State 繪製勾選符號
switch (State) {
case cbChecked: {
Canvas->Pen->Color = FCheckColor;
Canvas->Pen->Width = 2;
BT--; BB--; // 微調位置
// 畫 × 號:兩條對角線
Canvas->MoveTo(BL+3, BT+4); Canvas->LineTo(BR-3, BB-2);
Canvas->MoveTo(BR-3, BT+4); Canvas->LineTo(BL+3, BB-2);
} break;
case cbGrayed: {
if (Down) {
Canvas->Pen->Color = clBtnFace;
Canvas->Brush->Color = clBtnFace;
Canvas->Rectangle(BL+2, BT+2, BR-1, BB-1);
}
Canvas->Brush->Color = clBtnShadow;
Canvas->Rectangle(BL+2, BT+2, BR-1, BB-1); // 灰態填滿
} break;
}
// 焦點虛線框
Canvas->Brush->Color = clBtnFace;
Rect = Bounds(TX-1, TY, Canvas->TextWidth(Caption)+3, Canvas->TextHeight(Caption)+1);
Canvas->FrameRect(Rect);
if (FFocused) Canvas->DrawFocusRect(Rect);
}
void __fastcall TXCheckBox::MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y) {
SetFocus(); FFocused = true;
TCustomControl::MouseDown(Button, Shift, X, Y);
MouseCapture = true; Down = true;
}
void __fastcall TXCheckBox::MouseUp(TMouseButton Button, TShiftState Shift, int X, int Y) {
MouseCapture = false; Down = false;
if (X>=0 && X<=Width && Y>=0 && Y<=Height) Checked = !Checked;
TCustomControl::MouseUp(Button, Shift, X, Y);
}
void __fastcall TXCheckBox::KeyDown(WORD &Key, TShiftState Shift) {
if (Key == VK_SPACE) Down = true;
TCustomControl::KeyDown(Key, Shift);
}
void __fastcall TXCheckBox::KeyUp(WORD &Key, TShiftState Shift) {
if (Key == VK_SPACE) { Down = false; Checked = !Checked; }
TCustomControl::KeyUp(Key, Shift);
}
TCaption __fastcall TXCheckBox::GetCaption() { return Text; }
void __fastcall TXCheckBox::SetCaption(const TCaption& Value) {
if (Text != Value) { Text = Value; Invalidate(); }
}
void __fastcall TXCheckBox::SetState(TCheckBoxState Value) {
if (FState != Value) { FState = Value; Paint(); Click(); }
}
bool __fastcall TXCheckBox::GetChecked() { return State == cbChecked; }
void __fastcall TXCheckBox::SetChecked(bool Value) {
State = Value ? cbChecked : cbUnchecked;
}
void __fastcall TXCheckBox::SetCheckColor(TColor Value) {
FCheckColor = Value; Paint();
}
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
TXCheckBox* x = new TXCheckBox(this);
x->Parent = this;
x->Caption = "中文測試 English";
x->CheckColor = clRed; // 紅色 × 號
x->Left = 100; x->Top = 100;
}
GlyphChecked/GlyphUnchecked 屬性支援圖片勾選樣式。Alignment 屬性控制方框與文字相對位置。此實作展示了 VCL 自繪元件的核心模式:繼承 TCustomControl、處理 Paint、管理狀態變數、正確轉發滑鼠鍵盤訊息、提供標準屬性介面。開發者可依此範本建立各類自訂外觀的互動控制項。