|
不规则窗体的应用增加软件的吸引力 下一步要做的就是将已经创建好的区域显示在屏幕上,同样也是使用WINDOWS API 函数来实现,这次用到的是SetWindowRgn函数。 WINDOWS API 函数在Borland C++ Builder 头文件中均已定义,在应用程序中使用这些API函数就象使用C++的普通库函数一样。 准备工作
程序中引用图片 void __fastcall TForm1::FormCreate(TObject *Sender) { < 。 < 。 < 。 Image1->Picture->LoadFromFile(".\\face.bmp"); Width=Image1->Width; Height=Image1->Height; Repaint(); < 。 < 。 < 。 } 此时,窗体的大小已能跟随所用图片的大小而改变,但仍旧是传统的WINDOWS界面,要想显示成具有图片轮廓的窗体外形,就需要使用前文介绍的WINDOWS API函数将不需要显示的部分抠去。 抠像方法一 HRGN tepRgn; for(y=0;y<Image1->Height;y++) for(x=0;x<Image1->Width;x++) if(Image1->Canvas->Pixels[x][y]==clWhite) { < tepRgn=CreateRectRgn(x,y,x+1,y+1); CombineRgn(WndRgn,WndRgn,tepRgn,RGN_XOR); DeleteObject(tepRgn); } 这种方法的优点是处理比较简单,缺点是处理速度太慢,尤其是在处理大幅图片时,往往要4~5秒的时间才能将窗体显示出来。因此产生了通过另外的途径快速勾勒图片轮廓的想法。 抠像方法二 register int x,y; int l,r; POINT *a; bool lb,rb; HRGN WndRgn,TempRgn,; if((a=(POINT *)malloc(800*2*(sizeof(POINT))))==NULL) { ShowMessage("申请内存失败!"); exit(0); } l=0;r=Image1->Height*2-1; WndRgn=CreateRectRgn(0,0,Image1->Width,Image1->Height); for(y=0;y<Image1->Height;y++) { lb=true; for(x=0;x<Image1->Width;x++) if(Image1->Canvas->Pixels[x][y]!=clWhite) { a[l].x=x; a[l].y=y; lb=false; break; } if(lb) a[l]=a[l-1]; l++; rb=true; for(x=Image1->Width-1;x>=0;x--) if(Image1->Canvas->Pixels[x][y]!=clWhite) { a[r].x=x; a[r].y=y; rb=false; break; } if(rb) a[r]=a[r+1]; r--; } TempRgn=CreatePolygonRgn(a,Image1->Height*2,ALTERNATE); CombineRgn(WndRgn,WndRgn,TempRgn,RGN_AND); DeleteObject(TempRgn); < free(a); 程序中对每一像素行都从左右两个方向分别扫描,找到两边的分界点存入数组。 不过这个方法也存在一些缺陷,那就是图片的内凹部分轮廓并未表现出来。从下图中可以看出:
void __fastcall TForm1::FormCreate(TObject *Sender) { register int x,y; int l,r; POINT *a; bool lb,rb; HRGN WndRgn,TempRgn,tepRgn; Width=800;Height=600; if((a=(POINT *)malloc(800*4*(sizeof(POINT))))==NULL) { ShowMessage("申请内存失败!"); exit(0); } Image1->Picture->LoadFromFile(".\\face.bmp"); Width=Image1->Width; Height=Image1->Height; Repaint(); l=0;r=Image1->Height*2-1; WndRgn=CreateRectRgn(0,0,Image1->Width,Image1->Height); < //应用方法二产生轮廓坐标点数组 for(y=0;y<Image1->Height;y++) { lb=true; for(x=0;x<Image1->Width;x++) if(Image1->Canvas->Pixels[x][y]!=clWhite) { a[l].x=x+1; a[l].y=y; lb=false; break; } if(lb) a[l]=a[l-1]; l++; rb=true; for(x=Image1->Width-1;x>=0;x--) if(Image1->Canvas->Pixels[x][y]!=clWhite) { a[r].x=x; a[r].y=y; rb=false; break; } if(rb) a[r]=a[r+1]; r--; } //应用方法一抠去图片内凹部分 r=Image1->Height*2-1; for(y=0;y<Image1->Height;y++){ for(x=a[y].x;x<a[r].x;x++) if(Image1->Canvas->Pixels[x][y]==clWhite) { < tepRgn=CreateRectRgn(x,y,x+1,y+1); CombineRgn(WndRgn,WndRgn,tepRgn,RGN_XOR); DeleteObject(tepRgn); } r--; } //将图片外围部分抠去 TempRgn=CreatePolygonRgn(a,Image1->Height*2,ALTERNATE); CombineRgn(WndRgn,WndRgn,TempRgn,RGN_AND); DeleteObject(TempRgn); free(a); //显示不规则窗体 SetWindowRgn(Handle,WndRgn,true); SetWindowPos(Handle,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); } 至此,一个漂亮的程序界面就出现在你的屏幕上了。见下图:
如有疑问,请致函 taozc@sina.com.cn 。 |