史萊姆論壇

史萊姆論壇 (http://forum.slime.com.tw/)
-   程式語言討論區 (http://forum.slime.com.tw/f76.html)
-   -   用C++Builder設計一個不規則形狀表單 (http://forum.slime.com.tw/thread151891.html)

魔術王子 2005-06-21 12:19 PM

用C++Builder設計一個不規則形狀表單
 
請先用編輯軟體將不顯示部分塗成藍色(Blue)
然後再表單上插入一個TImage物件,載入這張圖
然後再Form1的OnActivate事件填入
語法:

void __fastcall TForm1::FormActivate(TObject *Sender)
{
    HRGN rgn1,rgn2;
    int x,y,startx,endx;
    if(rgn1!=0)DeleteObject(rgn1);
    rgn1=0;
    LockWindowUpdate(Handle);
    for(y=0;y<Image1->Height-1;y++)
    {
        x=0;
        startx=0;
        endx=x;
        do
        {
            while((Image1->Canvas->Pixels[x][y]==clBlue)&&(x<=Image1->Width)){x++;}
            startx=x;
            x++;
            while((Image1->Canvas->Pixels[x][y]!=clBlue)&&(x<=Image1->Width)){x++;}
            endx=x;
            if(startx!=Image1->Width)
            {
                if(endx==Image1->Width)endx--;
                if(rgn1==0)
                {
                    rgn1=CreateRectRgn(startx+1,y,endx,y+1);
                }
                else
                {
                    rgn2=CreateRectRgn(startx+1,y,endx,y+1);
                    if(rgn2!=0)
                    {
                        CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
                    }
                    DeleteObject(rgn2);
                }
            }
        }while(x<Image1->Width-1);
    }
    LockWindowUpdate(0);
    SetWindowRgn(Handle,rgn1,true);
}
//---------------------------------------------------------------------------

Image1的OnDblClick事件填入(不填也行,只是要結束程式會有點麻煩)
語法:

void __fastcall TForm1::Image1DblClick(TObject *Sender)
{
    Close();
}
//---------------------------------------------------------------------------

本程式節錄自RUN!PC 67期 李明樹先生發表

mini 2005-06-21 01:43 PM

塗成藍色(Blue) 是根據 clBlue 嗎?
不知其 RGB 值是多少 (0000FF嗎)?
方法看似以 像素做點的掃瞄,初期好像很費時的說

^^
由於自己沒用過 C++Builder 所以
請不吝指教

Thx share ^^

魔術王子 2005-06-21 02:01 PM

引用:

方法看似以 像素做點的掃瞄,初期好像很費時的說

應該還好啦
利用3個API函數
CreateRectRgn建立方形區塊

CombineRgn組合區塊

SetWindowRgn將區域設給視窗

他是的確一行一行掃描若不是隱藏顏色,就將他們建成一行區塊(CreateRectRgn)
等到遇到隱藏顏色或該行結束時,就將他和之前的區域結合(CombineRgn)成一個大區域
才進行下一組或下一行

等全部都掃描完後再將視窗是成本區域(SetWindowRgn)

while((Image1->Canvas->Pixels[x][y]==clBlue)&&(x<=Image1->Width)){x++;}

while((Image1->Canvas->Pixels[x][y]!=clBlue)&&(x<=Image1->Width)){x++;}

顏色在這2行設定(小王子比較喜歡藍色,記住圖中不能有藍色喔,不然會一起隱藏)

mini 2005-06-21 02:36 PM

原來是以行為單位
這個行就是 高為1的區塊 嘍

第一個 while 是找 第一個clBlue 訂出(寬的)起點
第二個 while 是訂出 (寬的)終點
這樣就可以算出一行了

是否?

c++對自己來說
還真費神的說

再次感謝 王子 的說 ^^

===============

感覺
第二個 while 可以從右側來找的說
因為就算是不規則型
還是會以充分利用有效面積來規劃
平均下來不知會不會比較快而有效率

對了再問一個
如果中間內部有 藍色 那是否可形成 簍空的 表單的說 ?

魔術王子 2005-06-21 03:38 PM

引用:

如果中間內部有 藍色 那是否可形成 簍空的 表單的說 ?

沒錯

while((Image1->Canvas->Pixels[x][y]==clBlue)&&(x<=Image1->Width)){x++;} 這行是算出要隱藏的部份
startx=x; 算完後就記錄要顯示的部份開頭
x++;
while((Image1->Canvas->Pixels[x][y]!=clBlue)&&(x<=Image1->Width)){x++;} 開始讀取顯示的部份
endx=x; 紀錄顯示部分的結尾
if(rgn1==0) 若rgn1為零,表示第一次建
{
rgn1=CreateRectRgn(startx+1,y,endx,y+1);
}
else 表示已經建過了,就已rgn2來表示,再和rgn1做CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
{
rgn2=CreateRectRgn(startx+1,y,endx,y+1);
if(rgn2!=0)
{
CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
}
DeleteObject(rgn2);
}


所有時間均為台北時間。現在的時間是 07:57 AM

Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2025, Jelsoft Enterprises Ltd.

『服務條款』

* 有問題不知道該怎麼解決嗎?請聯絡本站的系統管理員 *


SEO by vBSEO 3.6.1