史萊姆論壇

返回   史萊姆論壇 > 專業主討論區 > 程式語言討論區
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


發文 回覆
 
主題工具 顯示模式
舊 2005-06-21, 12:19 PM   #1
魔術王子
版區管理員
 
魔術王子 的頭像
榮譽勳章
UID - 115097
在線等級: 級別:42 | 在線時長:1989小時 | 升級還需:32小時級別:42 | 在線時長:1989小時 | 升級還需:32小時
註冊日期: 2004-01-13
住址: 魔術學園
文章: 2971
精華: 0
現金: 14880 金幣
資產: 2678510 金幣
預設 用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期 李明樹先生發表
魔術王子 目前線上  
送花文章: 1527, 收花文章: 1554 篇, 收花: 3893 次
回覆時引用此帖
舊 2005-06-21, 01:43 PM   #2 (permalink)
管理版主
 
mini 的頭像
榮譽勳章
UID - 4144
在線等級: 級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時
註冊日期: 2002-12-07
文章: 13314
精華: 0
現金: 26367 金幣
資產: 3024227 金幣
預設

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

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

Thx share ^^
mini 目前離線  
送花文章: 2006, 收花文章: 7984 篇, 收花: 26785 次
回覆時引用此帖
舊 2005-06-21, 02:01 PM   #3 (permalink)
版區管理員
 
魔術王子 的頭像
榮譽勳章
UID - 115097
在線等級: 級別:42 | 在線時長:1989小時 | 升級還需:32小時級別:42 | 在線時長:1989小時 | 升級還需:32小時
註冊日期: 2004-01-13
住址: 魔術學園
文章: 2971
精華: 0
現金: 14880 金幣
資產: 2678510 金幣
預設

引用:
方法看似以 像素做點的掃瞄,初期好像很費時的說
應該還好啦
利用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行設定(小王子比較喜歡藍色,記住圖中不能有藍色喔,不然會一起隱藏)
魔術王子 目前線上  
送花文章: 1527, 收花文章: 1554 篇, 收花: 3893 次
回覆時引用此帖
舊 2005-06-21, 02:36 PM   #4 (permalink)
管理版主
 
mini 的頭像
榮譽勳章
UID - 4144
在線等級: 級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時級別:97 | 在線時長:9804小時 | 升級還需:192小時
註冊日期: 2002-12-07
文章: 13314
精華: 0
現金: 26367 金幣
資產: 3024227 金幣
預設

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

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

是否?

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

再次感謝 王子 的說 ^^

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

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

對了再問一個
如果中間內部有 藍色 那是否可形成 簍空的 表單的說 ?
mini 目前離線  
送花文章: 2006, 收花文章: 7984 篇, 收花: 26785 次
回覆時引用此帖
舊 2005-06-21, 03:38 PM   #5 (permalink)
版區管理員
 
魔術王子 的頭像
榮譽勳章
UID - 115097
在線等級: 級別:42 | 在線時長:1989小時 | 升級還需:32小時級別:42 | 在線時長:1989小時 | 升級還需:32小時
註冊日期: 2004-01-13
住址: 魔術學園
文章: 2971
精華: 0
現金: 14880 金幣
資產: 2678510 金幣
預設

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

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);
}
魔術王子 目前線上  
送花文章: 1527, 收花文章: 1554 篇, 收花: 3893 次
回覆時引用此帖
發文 回覆



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 08:54 AM


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


SEO by vBSEO 3.6.1