本文論述了用Delphi進行圖形界面修飾的技術,給出了窗口漸變色背景、3D邊界、3D邊框的實現源代碼和一個軟件界面的實例。
作為一個程序員,在開發程序的時候,都希望自己程序的界面美觀一些,與眾不同一些,有自己鮮明的特色,這需要美化自己的界面。一般的方法是用圖形工具制作一個圖形界面,再經過簡單的編程便可獲得一個理想的效果,很多能夠界面換膚的程序大多也基於這種思
想;但程序員一般不精通圖形制作工具,請外面的美工來做也不方便,其實對一般的3D效果,我們自己也可用程序做。
編程方式實現3D效果的方法
為了改變電腦早期時候的文字界面的單一狀況,各大軟件公司都作出了不懈努力,先後推出了作為圖形處理工業標准的OpenGL和微軟研發的Direct3D,至於一些公司自用的3D技術更是不計其數。但本文提出的方法不需要上面大公司的技術,純粹用Delphi的基本函數來實現比較逼真的3D效果。
我以前作過一個卡拉OK電腦點歌程序,點歌方式有多種,其中有一種傳統的點歌方式叫編碼點歌,它需要在屏幕上畫一個點歌鍵盤,用鼠標點擊鍵盤(觸摸屏時用手觸摸)輸入歌曲編碼,其界面如下圖所示:
上圖中除了迎客松的圖片外,其它如背景、銅柱邊框、3D鍵盤等都是由程序實現的,下面我對實現程序予以簡單說明,上圖界面的完整實現請看本文附帶的源程序。
在給出程序之前先說一下技術思想,Delphi中有些對象具有畫布屬性Canvas,它本身也是一個對象,它具有很多屬性和方法,這裡只列出本文用到的幾個。
Canvas.Brush.Style:=bsClear;//設置畫刷風格
Canvas.pen.color:=rgb(R,G,B);// 設置畫筆顏色
Canvas.pen.style:=psSolid;// 設置畫筆風格
Canvas.pen.width:=1;//設置畫筆寬度
procedure MoveTo(X, Y: Integer);
//將畫筆移到坐標(X, Y) 處作為畫畫的起點
procedure LineTo(X, Y: Integer);
//從當前位置畫一條直線到坐標(X, Y) 處
procedure RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer);
//根據給定的參數畫一個圓角矩形,X3、Y3用於確定圓角大小
下面給出3D效果制作子程序:
1、 背景制作子程序
本段程序是用來畫背景,只要給出不同的顏色RGB值就能畫出不同的背景。下面的子程序都是利用對象的畫布Canvas並按一定的算法來生成效果。
procedure draw_bk(Sender:TForm;R,G,B:integer);
var i,j,k:integer;
begin
with Sender do
begin
canvas.pen.style:=psSolid;
canvas.pen.width:=1;
k:=(B div 3)*2;
for i:=0 to 480 do
begin
if i<k then j:=0 else j:=j+1;
if j>B then j:=B;
Canvas.pen.color:=rgb(R,G,B-j);
canvas.moveTo(0,i);
canvas.lineTo(640,i);
end;
end;
end;
2、 邊框周圍銅柱子程序
本段程序是用來畫窗口周圍的銅柱,只要給出不同的顏色RGB值就能畫出不同顏色的柱子。
procedure draw_roll(Sender:TForm;X0,Y0,W,H,R,G,B,lw:integer);
var i,J,j1,J2,J3,m,X,Y:integer;
begin
J1:=R div lw-2;
J2:=G div lw;
J3:=B div lw+2;
m:=lw div 3;
with Sender do
begin
for i:=0 to lw do
begin
if i<m then j:=m-i else j:=i-m;
Canvas.pen.color:=rgb(R-J1*J,G-J2*J,B-J3*J);
canvas.moveTo(i+X0,i+Y0);
canvas.lineTo(i+X0,H-i+Y0);
Canvas.pen.color:=rgb(R-J1*J,G-J2*J,B-J3*J);
canvas.moveTo(W-i-1+X0,i+Y0);
canvas.lineTo(W-i-1+X0,H-i+Y0);
Canvas.pen.color:=rgb(R-J1*J,G-J2*J,B-J3*J);
canvas.moveTo(i+X0,i+Y0);
canvas.lineTo(W-i+X0,i+Y0);
Canvas.pen.color:=rgb(R-J1*J,G-J2*J,B-J3*J);
canvas.moveTo(i+X0,H-i+Y0);
canvas.lineTo(W-i+X0,H-i+Y0);
end;
end;
end;
3、中間銅柱子程序
本段程序是用來畫窗口中間的銅柱,只要給出不同的顏色RGB值就能畫出不同顏色的柱子。
procedure draw_sroll(Sender:TForm;X0,Y0,W,H,R,G,B,lw:integer);
var i,J,j1,J2,J3,m,X,Y,i1,i2:integer;
begin
J1:=R div lw-2;
J2:=G div lw;
J3:=B div lw+2;
m:=lw div 3;
with Sender do
begin
for i:=0 to lw do
begin
i1:=i;
i2:=i;
if h=0 then i1:=0;
if w=0 then i2:=0;
if i<m then j:=m-i else j:=i-m;
Canvas.pen.color:=rgb(R-J1*J,G-J2*J,BJ3*J);
canvas.moveTo(i1+X0,i2+Y0);
canvas.lineTo(i1+W+X0,i2+H+Y0);
end;
end;
end;
4、3D框制作子程序
本段程序是用來畫控件周圍的邊框,使該控件看起來有立體感,只要給出不同的顏色RGB值就能畫出不同顏色的邊框,ww是立體景深。
procedure draw_rect(Sender:TForm;X0,Y0,W,H,R,G,B,lw,ww,fg:integer);
var ii,i,J,j1,J2,J3,m:integer;
begin
J1:=R div lw-2;
J2:=G div lw;
J3:=B div lw+2;
m:=lw div 3;
if fg=1 then{fg=0 ê.°.}
begin
j1:=j1 div 2+(j1+2) div 3;
j2:=j2 div 2+(j2+2) div 3;
j3:=j3 div 2+(j3+2) div 3;
end;
with Sender do
begin
Canvas.Brush.Style:=bsClear;
for ii:=0 to lw do
begin
if fg=0 then
begin
i:=ii;
if i<m then j:=m-i else j:=i-m;
end
else i:=lw-ii;
j:=ii;
Canvas.pen.color:=rgb(R-J1*J,G-J2*J,B-J3*J);
canvas.RoundRect(i+X0-lw,i+Y0-lw,X0+W-i+lw, H+Y0-i+lw,ww,ww);
end;
end;
end;
利用以上子程序就可實現一些3D效果,實現的算法就是利用循環語句作畫,至於語句為什麼要這樣寫,這是我通過多次試驗調試出來的,正因為如此該算法不可能很完善,您可以對此改進作出更完美的效果。
最後,利用上面提供的子程序就可完成上圖所示的界面編制,其程序代碼如下:
procedure TForm2.FormPaint(Sender: TObject);
begin
draw_bk(Form2,60,60,255);//畫藍色漸變背景
draw_roll(Form2,0,0,640,480,250,200,100,10);
//畫邊框周圍銅柱
with Image1 do draw_rect(Form2,left,top,width,height, 250,200,100,10,1,1); //畫圖片框
with Panel1 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel2 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel3 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel4 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel5 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel6 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel7 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel8 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel9 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel10 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel11 do draw_rect(Form2,left,top,width, height*2+2,250,238,238,10,1,1);
with Panel13 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel14 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel16 do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
//以上畫鍵盤
with sele_fun do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with Panel15 do draw_rect(Form2,left,top,222,height, 250,238,238,10,1,1);
with Panel15 do draw_rect(Form2,left-11,top-11,242, 350,250,258,238,10,1,1);
draw_sroll(Form2,291,5,0,470,250,200,100,12);
with gd do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
with gk do draw_rect(Form2,left,top,width,height, 250,238,238,10,1,1);
end;
本文帶有源程序,該程序在Delphi 6.0下調試通過,無需擴展控件支持,純軟件方式實現,在界面設計上具有很大的靈活性,與圖片界面相比有其方便性,並且制作出來的界面有自己鮮明的特色。
結束語
本文闡述了不借助OpenGL和Direct3D圖形庫自己編程實現3D效果的方法,給出了實現一個鍵盤界面的完整源代碼。在工作中究竟使用什麼來實現3D和其它效果,要看工作性質而定,例如開發圖形效果表現豐富的游戲軟件,就要用到OpenGL或Direct3D技術,至於一些行業應用和工具軟件一般使用手工編程改善一下界面效果即可,就像上面的代碼,將比使用圖形庫的程序大大節省資源,而且易維護、易管理、兼容性也好。