2015-02-07 31 views
2

我正在自定義OnDrawItem事件以在項目名稱旁邊繪製圖標。 這裏是迄今爲事件的OnDrawItem我的代碼:在ComboBox DrawItem事件中複製TImageList中的透明(32位阿爾法)位圖

void __fastcall Form1::ComboBox1DrawItem(TWinControl *Control, int Index, 
             TRect &Rect, TOwnerDrawState State) 
{ 
TComboBox* CB = static_cast<TComboBox*>(Control); 
CB->Canvas->FillRect(Rect); 

boost::scoped_ptr<Graphics::TBitmap> bitmap(new Graphics::TBitmap()); 
bitmap->PixelFormat = pf32bit; 
bitmap->AlphaFormat = afPremultiplied; 

ImageList1->GetBitmap(Index, bitmap.get()); 

bitmap->AlphaFormat = afPremultiplied; 

if (bitmap->Canvas->Handle) 
    { 
    // structure for alpha blending 
    BLENDFUNCTION bf; 
    bf.BlendOp    = AC_SRC_OVER; 
    bf.BlendFlags   = 0; 
    bf.SourceConstantAlpha = 0xFF;   // 0x00 (transparent) through 0xFF (opaque) 
    bf.AlphaFormat   = AC_SRC_ALPHA; // Use bitmap alpha 

    ::AlphaBlend(CB->Canvas->Handle, // handle to destination DC 
      Rect.Left + 2,    // x-coord of upper-left corner 
      Rect.Top,     // y-coord of upper-left corner 
      bitmap->Width,    // destination width 
      bitmap->Height,   // destination height 
      bitmap->Canvas->Handle, // handle to source DC 
      0,       // x-coord of upper-left corner 
      0,       // y-coord of upper-left corner 
      bitmap->Width,    // source width 
      bitmap->Height,   // source height 
      bf       // alpha-blending function 
      ); 
    } 

    Rect = Bounds(Rect.Left + 20 + 2, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top); 

    DrawTextW(CB->Canvas->Handle, CB->Items->Strings[Index].c_str(), -1, &Rect, DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); 
} 

當然,問題是得到一個透明TImageList1拷貝到透明TBitmap保存32位alpha透明/半透明。目前,我在出現的TBitmap中將它與白色背景相結合。

只是要清楚,TImageListColorDepth是在其加載圖像,它和之前的圖像設置爲cd32bitDrawingStyle = dsTransparent是透明的,沒有任何問題存在。

解決這個問題的訣竅是什麼?

更新和我的最終解決方案

基於答覆這裏這裏是別人誰可能需要在將來我最後的工作代碼。這當然只是一個模板代碼,您可能需要根據自己的需要進一步進行自定義。

void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index, TRect &Rect, TOwnerDrawState State) 
{ 
if (Index >= 0) 
     { 
     TComboBox* CB  = static_cast<TComboBox*>(Control); 
     CB->Canvas->FillRect(Rect); 
     // Note - ImageList1 already has DrawingStyle set to dsTransparent   
     ImageList1->Draw(CB->Canvas, Rect.Left + 2, Rect.Top, 0); 
     Rect = Bounds(Rect.Left + ImageList1->Width + 2 + 2, Rect.Top, Rect.Right - Rect.Left - ImageList1->Width - 2, Rect.Bottom - Rect.Top); 
     DrawTextW(CB->Canvas->Handle, CB->Items->Strings[Index].c_str(), -1, &Rect, DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); 
     } 
} 
+4

爲什麼不讓圖像列表繪製?你可以使用它的繪製方法。否則,請參閱http://stackoverflow.com/questions/13352497/delphi-get-bitmap-from-a-timagelist。 – 2015-02-08 01:57:43

+0

@SertacAkyuz謝謝你,這很有效......如果你把它變成一種答案,我會非常樂意接受它。否則,我會等待一段時間,自己做出答案。 – Coder12345 2015-02-08 15:13:07

+0

完成。但是,你的想法是一個更詳細的答案,請張貼,我會刪除我的。別客氣。 – 2015-02-08 16:02:54

回答

2

你並不需要去嘗試,並從圖像列表搶原始位圖,因爲圖像列表本身知道如何繪製履行透明度信息。你可以使用它的Draw方法。

否則,答案here建議在調用GetBitmap之前將AlphaFormat設置爲'afIgnored'應該保持透明度。