|  | 
| 
 | |||||||
| 論壇說明 | 
| 歡迎您來到『史萊姆論壇』  ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 | 
|    | 
|  | 主題工具 | 顯示模式 | 
|  2005-06-21, 12:19 PM | #1 | 
| 版區管理員  |  用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);
}
//---------------------------------------------------------------------------語法: void __fastcall TForm1::Image1DblClick(TObject *Sender)
{
    Close();
}
//--------------------------------------------------------------------------- | 
|   | 
		送花文章: 1542,
		
			
		   | 
|  2005-06-21, 02:01 PM | #3 (permalink) | |
| 版區管理員  |   引用: 
 利用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行設定(小王子比較喜歡藍色,記住圖中不能有藍色喔,不然會一起隱藏) | |
|   | 
		送花文章: 1542,
		
			
		   | 
|  2005-06-21, 02:36 PM | #4 (permalink) | 
| 管理版主              |   原來是以行為單位 這個行就是 高為1的區塊 嘍 第一個 while 是找 第一個clBlue 訂出(寬的)起點 第二個 while 是訂出 (寬的)終點 這樣就可以算出一行了 是否? c++對自己來說 還真費神的說 再次感謝 王子 的說 ^^ =============== 感覺 第二個 while 可以從右側來找的說 因為就算是不規則型 還是會以充分利用有效面積來規劃 平均下來不知會不會比較快而有效率 對了再問一個 如果中間內部有 藍色 那是否可形成 簍空的 表單的說 ? | 
|   | 
		送花文章: 2058,
		
			
		   | 
|  2005-06-21, 03:38 PM | #5 (permalink) | |
| 版區管理員  |   引用: 
 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); } | |
|   | 
		送花文章: 1542,
		
			
		   |