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