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

TListBox 自繪進階:圓角卡片風格多行項目完整實作

     編輯:關於C++

效果預覽

ListBox 自繪效果示意

核心技術點

  • Style = lbOwnerDrawFixed:啟用固定高度自繪模式
  • ItemHeight = 50:設定每項高度
  • 於 OnDrawItem 事件中完全自訂繪製邏輯
  • 使用 RoundRect 繪製圓角矩形實現卡片立體感
  • 支援選中/焦點狀態視覺區分
  • 結合 ImageList 顯示圖示
  • 單項顯示三行文字(主標題、副標題、備註)

完整實作程式碼

// 建構式初始化
__fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner) {
    lbxMain->Style = lbOwnerDrawFixed;
    lbxMain->Ctl3D = false;          // 移除 3D 邊框
    lbxMain->ItemHeight = 50;        // 固定項高
    pStrList = new TStringList;

    for (int i = 0; i < 10; ++i) {
        lbxMain->Items->Add("ListBox Items of " + String(i));
        // 使用 0x03 作為分隔符,儲存第二、三行文字
        pStrList->Add("Second of " + String(i) + String((char)0x03) + "Third of " + String(i));
    }
}

// 核心繪製邏輯
void __fastcall TMainForm::lbxMainDrawItem(TWinControl* Control, int Index,
    TRect& Rect, TOwnerDrawState State) {

    // 背景與文字預設色
    lbxMain->Canvas->Brush->Color = clWhite;
    lbxMain->Canvas->Font->Color = clBlack;
    lbxMain->Canvas->FillRect(Rect);

    // 卡片圓角背景
    lbxMain->Canvas->Brush->Color = TColor(0x00FFF7F7); // 淺藍底
    lbxMain->Canvas->Pen->Color = TColor(0x00131315);   // 深灰邊框
    lbxMain->Canvas->RoundRect(Rect.Left + 3, Rect.Top + 3,
        Rect.Right - 2, Rect.Bottom - 2, 8, 8);

    // 內層圓角產生立體感
    lbxMain->Canvas->RoundRect(Rect.Left + 3, Rect.Top + 3,
        Rect.Right - 3, Rect.Bottom - 3, 5, 5);

    // 選中狀態覆蓋
    if (State.Contains(odSelected)) {
        lbxMain->Canvas->Brush->Color = TColor(0x00FFB2B5); // 粉紅選中色
        lbxMain->Canvas->RoundRect(Rect.Left + 3, Rect.Top + 3,
            Rect.Right - 3, Rect.Bottom - 3, 5, 5);
        lbxMain->Canvas->Font->Color = clBlue;

        // 焦點虛線框處理(實際上是清除預設虛線框)
        if (State.Contains(odFocused))
            ::DrawFocusRect(lbxMain->Canvas->Handle, &Rect);
    }

    // 繪製圖示(垂直置中)
    ImageList1->Draw(lbxMain->Canvas, Rect.Left + 7,
        Rect.Top + (lbxMain->ItemHeight - ImageList1->Height) / 2,
        Index, true);

    // 第一行:主標題
    lbxMain->Canvas->TextOutA(Rect.Left + 42, Rect.Top + 4,
        lbxMain->Items->Strings[Index]);

    // 解析第二、三行文字
    String strTemp = pStrList->Strings[Index];
    int pos = strTemp.Pos((char)0x03);
    String second = strTemp.SubString(1, pos - 1);
    String third = strTemp.SubString(pos + 1, strTemp.Length());

    // 第二行
    lbxMain->Canvas->TextOutA(Rect.Left + 42, Rect.Top + 18, second.c_str());
    // 第三行
    lbxMain->Canvas->TextOutA(Rect.Left + 42, Rect.Top + 32, third.c_str());
}

輔助功能

  • 點擊顯示項目:OnClick 更新狀態列
  • 雙擊編輯:彈出模態對話框編輯三行文字,回寫至 ListBox 與 StringList
  • 無標題欄視窗拖移:WM_SYSCOMMAND + 0xF012 (SC_DRAGMOVE)
  • 視窗摺疊/展開:切換高度與按鈕圖示

關鍵細節提醒

  1. 分隔符選擇:使用不可見字元 0x03 避免與使用者輸入衝突
  2. 座標計算:文字輸出位置需手動換行,ItemHeight 需配合行數設定
  3. 焦點框處理:DrawFocusRect 重複呼叫可切換顯示/隱藏,此處用於清除預設虛線框
  4. 資源釋放:FormDestroy 中 delete pStrList 防止記憶體洩漏

擴充方向

  • 改用 lbOwnerDrawVariable 支援可變項高
  • 加入滑鼠懸停高亮、動畫過渡效果
  • 支援 HTML/RTF 富文本渲染
  • 虛擬模式處理大量資料
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved