線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3147
推到 Plurk!
推到 Facebook!

將 ToolBar 設定顏色後,按鈕上的圖示要如何保持透明?

缺席
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-01-19 19:10:14 IP:218.19.xxx.xxx 未訂閱
各位好,我在程式中使用 ImageList 來配合 ToolBar 一起運作,一切都正常,但是當我將 ToolBar 的 Color 屬性設成其它的顏色 (例如:紅色) 後,ToolBar 按鈕上的圖示卻無法一併作 "透明" 的處理,也就是說圖示上應該 "透明" 的部份,全部都變成 clBtnFace 的顏色,請教各位先進,我要如何作才能讓 ToolBar 上的圖示在 ToolBar 的 Color 屬性作變更時,能隨著一併作底色的透明變化 (如下圖,讓圖一的按鈕上顯示為 clBtnFace 色的部份變成圖二的紅色) 呢?    圖一: 圖二:
m8815010
版主


發表:99
回覆:372
積分:289
註冊:2003-11-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-01-21 14:30:02 IP:61.63.xxx.xxx 未訂閱
引言: 各位好,我在程式中使用 ImageList 來配合 ToolBar 一起運作,一切都正常,但是當我將 ToolBar 的 Color 屬性設成其它的顏色 (例如:紅色) 後,ToolBar 按鈕上的圖示卻無法一併作 "透明" 的處理,也就是說圖示上應該 "透明" 的部份,全部都變成 clBtnFace 的顏色,請教各位先進,我要如何作才能讓 ToolBar 上的圖示在 ToolBar 的 Color 屬性作變更時,能隨著一併作底色的透明變化 (如下圖,讓圖一的按鈕上顯示為 clBtnFace 色的部份變成圖二的紅色) 呢? 圖一: 圖二:
RedSnow你好< >: 我個人覺得這是一個必然的現像,沒什麼特別的解法了< >!怎麼說呢? 因為真正說來,一張bmp圖並沒有什麼透明色的問題,也就是說以RGB3原色來說,跟本沒有透明色這種東西!即一張bmp圖而言,背景一定是有某種顏色構成的(可能多種),決不可能一張bmp圖說可以背景設成什麼透明的! 所以以你的原始狀況而言,每個icon圖都是一張張(8x8,也許)的圖,而圖的背景都是灰色系的顏色(不一定是clBtnFace),所以當你的toolbar是default色(clBtnFace)時,你會覺得ok,那只是剛好看不出來,而toolbar一換其它的顏色,icon圖的底色就顯現出來了! 那大家可能會有疑問,如桌面上的icon看似就是透明背景啊!或是一些圖像軟體都有提供透明處理,那又如何解釋呢?我個人估計都只是先經過一些透明處理手段去達成效果!明顯的,一個TToolBar元件是不可能有這種處理效果的! 以下是我之前遇到這類似問題的一小小些作法,沒什麼學問,不過就是改改bmp內容罷了! 以下是一個例子,假設圖一是原來的bmp圖,圖三是這張圖的內容,圖三圈選處是檔頭加上調色盤的資訊,色盤是32色的!並且我們已經先觀查圖檔data只有用到3種顏色,分別為0x00、0x03、0x04,而0x00這色是做底色用! 假設今天我要將這張圖貼在一個偏白色系的元件上時,這時我就會先改變這張圖的底色,如圖二,再貼上去,以達到視覺上的效果,也就是透明的感覺啦@ 至於怎麼改就得簡單啦,例如:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 if (OpenDialog1->Execute()) {
     Byte *ptr;
     Graphics::TBitmap* pBitmap=new Graphics::TBitmap;         try {
          pBitmap->LoadFromFile(OpenDialog1->FileName);  //載入原圖檔
          Image1->Picture->Assign(pBitmap);              //show出原圖檔的樣子              for (int y = 0; y < pBitmap->Height; y++) {    //讀取每個pixel的data
               ptr = (Byte *)pBitmap->ScanLine[y];                   for (int x = 0; x < pBitmap->Width; x++) {
                    if (ptr[x]==0x00)         //當發現這點pixel是底色時
                        ptr[x]=0x08;          //則把它換成偏白色系的色
               }
          }        Image2->Picture->Assign(pBitmap);
  }
  catch (...)
  {
    ShowMessage("Could not load or alter bitmap");
  }
  delete pBitmap;
  }
}

當然上以的作法你必需先看看這些圖的底色到底是那一色,並且看看圖中的調色盤為何,有那些其它的顏色可以讓你更換! 嗯,所以可以依此精神動態改變一張bmp的底色(這時這張bmp是存於memory中的),再貼上ToolBar上,以符合ToolBar的顏色! 另外也可以用靜態的方式,即先做好一張張不同底色的圖,再assign給不同的imagelist,如imagelist1放紅色底圖的、imagelist放灰色底圖的.... 然後當ToolBar換顏色時,再利用切換imagelist以達成效果! 以上是之前的小小小心得,不保高明,請參著參著! *如果載入的圖是.
RedSnow
版主


發表:79
回覆:1322
積分:845
註冊:2003-12-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-01-21 23:59:16 IP:218.19.xxx.xxx 未訂閱
m8815010 版主您好:    其實我對 ImageList 與 ToolBar 這兩個物件的配合是否有 Bug?是存在著合理懷疑的,我們可以做個測試:    1. 先將測試環境設成如下圖的狀態:     2. 接著把按鈕項目的 Marked 屬性設為 true 如下圖: 上述的動作都是在 Design Time 的狀態設定的,並未經過任何程序的處理,但是可以看到原本是 clBtnFace 顏色的部份已經變成紅色的了,換言之;雖然將按鈕項目的 Marked 屬性設為 true 的效果並非是我想要的,但是我們可以由此推論出 ToolBar 應該是可以對取用自 ImageList 的圖示做到 "透空" 的動作才對。 我看了您的建議後,覺得這似乎也是我在目前資訊有限的狀態下可以做的,因此我就以 "代換 ImageList 內圖示的底色" 為目標另外做了一些測試,結果是差強人意,而且會產生一個 "怪現象",我是這麼寫的:

測試環境:Windows 2000 Pro + BCB 4.0
==========================    TImageList *ImageList1;
TToolBar *ToolBar1;
TButton *Button1;
TColorDialog *ColorDialog1;
TImage *Image1;    void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if(ColorDialog1->Execute()){
        ImageList1->BkColor = ToolBar1->Color;
        ToolBar1->Color = ColorDialog1->Color;            TImageList *tmpImagesList = new TImageList(NULL);            Graphics::TBitmap *OrigBmp = new Graphics::TBitmap();
        OrigBmp->Transparent = true;
        OrigBmp->Width  = ImageList1->Width;
        OrigBmp->Height = ImageList1->Height;            Graphics::TBitmap *DestBmp = new Graphics::TBitmap();
        DestBmp->Canvas->CopyMode = cmSrcCopy;
        DestBmp->Canvas->Brush->Color = ColorDialog1->Color;
        DestBmp->Width  = ImageList1->Width;
        DestBmp->Height = ImageList1->Height;            for(int i=0; iCount; i++){
            ImageList1->GetBitmap(i, OrigBmp);
            DestBmp->Canvas->FillRect(Rect(0, 0, DestBmp->Width, DestBmp->Height));
            DestBmp->Canvas->Draw(0, 0, OrigBmp);    // 很奇怪,以下這行敘述與要做的動作無關 (原先是拿來查看轉換過程中圖像變化之用的),
// 但是若拿掉的話,結果竟然會變得不正常....
            Image1->Picture->Bitmap->Assign(OrigBmp);
            tmpImagesList->Add(DestBmp, NULL);
        }
        ImageList1->Assign(tmpImagesList);            delete DestBmp;
        DestBmp = NULL;
        delete OrigBmp;
        OrigBmp = NULL;
        delete tmpImagesList;
        tmpImagesList = NULL;
    }
}
上述的程序基本上可以讓按鈕圖示的 "底色" 與 ToolBar 及按鈕其它部分的顏色達到一致,但這似乎仍不是正解,而且以紅色標示用來測試之用的那一行還不能拿掉呢,若拿掉的話就會不正常,這不但奇怪,而且也讓我頭疼,如果版主或其他有經驗的先進們知道問題出在那裡的話?還望能指點一二。 發表人 - RedSnow 於 2005/01/22 00:03:52 發表人 - RedSnow 於 2005/01/22 00:06:19
系統時間:2024-05-05 1:28:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!