国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

C++ 中不規(guī)則窗體的快速顯示

2019-11-17 05:38:10
字體:
供稿:網(wǎng)友

  傳統(tǒng)的WINDOWS應用軟件界面給人的感覺總是千篇一律的方方正正的窗體,看的時間長了難免會有些厭煩,總是希望能見到些不同一般的軟件界面。如今,相當數(shù)量的商業(yè)軟件在提供優(yōu)秀而強大的功能的同時,軟件的界面也是做得越來越漂亮,比如《超級解霸2000》中的界面插件,使用過的人一定對其華麗的外觀布滿好感。作為一個編程愛好者,假如自己寫出的軟件也擁有類似的界面,也許會吸引更多目光的注視。那么,我們現(xiàn)在就開始動手制作自己的漂亮界面吧。

  技術(shù)內(nèi)幕

  要想在自己的程序中加入不規(guī)則窗體的應用,你首先要熟悉幾個WINDOWS API函數(shù)的使用,它們是:橢圓形(或圓形)區(qū)域創(chuàng)建函數(shù)CreateEllipticRgn 、多邊形區(qū)域創(chuàng)建函數(shù)CreatePolygonRgn、 矩形區(qū)域創(chuàng)建函數(shù)CreateRectRgn、 帶圓角的矩形區(qū)域創(chuàng)建函數(shù)CreateRoundRectRgn。你可以用這些函數(shù)創(chuàng)建不同類型的窗體區(qū)域,也可以用WINDOWS API函數(shù)CombineRgn將幾個簡單區(qū)域組合成一個復雜區(qū)域。

  下一步要做的就是將已經(jīng)創(chuàng)建好的區(qū)域顯示在屏幕上,同樣也是使用WINDOWS API 函數(shù)來實現(xiàn),這次用到的是SetWindowRgn函數(shù)。

  WINDOWS API 函數(shù)在Borland C++ Builder 頭文件中均已定義,在應用程序中使用這些API函數(shù)就象使用C++的普通庫函數(shù)一樣。

  預備工作:為你的程序預備一幅背景圖片,推薦方法是: 在photoshop中打開圖片后使用磁性套索工具選取你所需要的圖象輪廓——復制——新建文件(背景使用白色)——粘貼——另存文件(PSD文件)——用ACDSee等看圖軟件將保存的PSD文件轉(zhuǎn)換為BMP文件face.bmp備用。

  程序中引用圖片

    打開Borland C++ Builder,在窗體上放置一個Image控件Image1,其Picture暫為空;在窗體上放置一個Popup菜單,編輯菜單項增加“Close”項(添加程序代碼使得激活彈出菜單時即可關(guān)閉應用程序)。程序中做如下處理:  

  void __fastcall TForm1::FormCreate(TObject *Sender)  

  {  

  Image1->Picture->LoadFromFile(".//face.bmp");  

  Width=Image1->Width;

  Height=Image1->Height;  

  Repaint();  

  }

  此時,窗體的大小已能跟隨所用圖片的大小而改變,但仍然是傳統(tǒng)的WINDOWS界面,要想顯示成具有圖片輪廓的窗體外形,就需要使用前文介紹的WINDOWS API函數(shù)將不需要顯示的部分摳去。  

  摳像方法一

    這是一種非常簡單的方法,采用對圖片逐行掃描的方式,將圖片像素點為白色的部分摳去,使用的方法是:在像素點四周產(chǎn)生一個包含幾個像素點的矩形,與原圖片采用異或方式摳去,程序如下:

  HRGN tePRgn; 

  for(y=0;yHeight;y++)  

  for(x=0;xWidth;x++)  

  if(Image1->Canvas->Pixels[x][y]==clWhite)  

  {

  < tepRgn=CreateRectRgn(x,y,x+1,y+1);  

  CombineRgn(WndRgn,WndRgn,tepRgn,RGN_XOR);  

  DeleteObject(tepRgn); 

  }

  這種方法的優(yōu)點是處理比較簡單,缺點是處理速度太慢,尤其是在處理大幅圖片時,往往要4~5秒的時間才能將窗體顯示出來。因此產(chǎn)生了通過另外的途徑快速勾勒圖片輪廓的想法。  

  摳像方法二

    這次我們采用另一個WINDOWS API函數(shù)CreatePolygonRgn(多邊形區(qū)域),使用這個函數(shù)時需為它預備圖片輪廓的坐標點數(shù)組及坐標點個數(shù),也是通過對圖片逐行掃描的方式,找到白色像素點與非白色像素點的分界點,將該點的坐標存入數(shù)組中,然后用CreatePolygonRgn函數(shù)一次就可以把圖片外圍的不用部分摳去,從而省去大量的處理時間。程序如下:  

  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("申請內(nèi)存失敗!");  

  exit(0); 

  }

  l=0;r=Image1->Height*2-1;  

  WndRgn=CreateRectRgn(0,0,Image1->Width,Image1->Height);  

  for(y=0;yHeight;y++)

  {  

  lb=true;  


  for(x=0;xWidth;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);

  程序中對每一像素行都從左右兩個方向分別掃描,找到兩邊的分界點存入數(shù)組。

  不過這個方法也存在一些缺陷,那就是圖片的內(nèi)凹部分輪廓并未表現(xiàn)出來。
  最終解決方案

    考慮到既不增加算法的復雜度,又可大幅度縮短不規(guī)則窗體的創(chuàng)建速度,因此采用綜合以上兩種方案,達到我們應用的目的,程序中首先應用方法二對圖片雙向掃描,產(chǎn)生輪廓坐標點數(shù)組,然后在圖片輪廓內(nèi)應用方法一將內(nèi)凹部分摳去,最后才用多邊形區(qū)域創(chuàng)建函數(shù)摳去圖片外圍部分。程序如下:

  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("申請內(nèi)存失敗!");  

  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);  

  < //應用方法二產(chǎn)生輪廓坐標點數(shù)組  

  for(y=0;yHeight;y++)  

  {  

  lb=true;

  for(x=0;xWidth;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--;  

  }  

  //應用方法一摳去圖片內(nèi)凹部分  

  r=Image1->Height*2-1;  

  for(y=0;yHeight;y++){  

  for(x=a[y].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);  

  //顯示不規(guī)則窗體  

  SetWindowRgn(Handle,WndRgn,true);  

  SetWindowPos(Handle,HWND_TOP,0,0,0,0,SWP_NOMOVE SWP_NOSIZE);  

  }  

  至此,一個漂亮的程序界面就出現(xiàn)在你的屏幕上了。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 湖口县| 陇南市| 灌南县| 邵武市| 湘潭市| 遂昌县| 昆明市| 界首市| 沧源| 钟祥市| 攀枝花市| 夹江县| 浦北县| 威信县| 清徐县| 紫云| 宁武县| 鸡东县| 甘谷县| 元氏县| 磐安县| 玛多县| 百色市| 盐亭县| 温州市| 双辽市| 泗阳县| 和顺县| 汉中市| 屯门区| 曲周县| 临泽县| 长寿区| 新乡县| 博爱县| 巫山县| 三原县| 连南| 安达市| 连南| 隆安县|