如何自創VCL沒有的Event或是Canvas |
|
lcsboy
版主 發表:87 回覆:622 積分:394 註冊:2002-06-18 發送簡訊給我 |
如何創造VCL原來沒有Event的原理, 可參考我的想法:
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=22595 如何在沒有Canvas屬性的VCL繪圖, 可參考我的想法:
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=22596 這個Demo 程式的畫面: 執行後, 滑鼠移到原本沒有MouseMove Event的ComboBox, 會在原本不能
直接繪圖的Panel上繪出紅色的區塊or綠色的區塊 發表人 - lcsboy 於 2002/12/01 03:34:30
附加檔案:23435_NewEvent.zip
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
此為轉貼資料 參考參考 http://cslin.auto.fcu.edu.tw/scteach/scteach88/lcdmea/newpage6.htm 在Windows的作業環境下,如果你想在視窗上畫圖,畫線,則你必須直接呼叫Windows的GDI函數,來達到圖形處理的目的。可是你必須控制一些較低階動作,在實作上非常不方便,所以C++ Builder就把這些GDI的函數及繪圖的處理步驟,封裝成TCanvas元件供使用者解決圖形處理的問題。而在VCL內就有許多視覺化元件都包含Canvas屬性,也就是說,你可以在包含有Canvas屬性的的視 覺化元件上面繪製圖形,像是TForm、TPaintBox、TImage…等元件。 基本上,C++ Builder的TCanvas元件封裝了Windows GDI三種等級的函數,這三種等級分別是High、Intermediate、Low。High等級內函數是用來畫線、造型及繪制文字,在TCanvas元件內相對應的方法有LineTo、Ellipse、TextOut等;Intermediate等級的函數則是用來自定文字、圖形及管理圖像,像是TCanvas的Pen、Brush、Font、CopyRect、BrushCopy;Low等級是直接去呼叫Windows GDI的函數,使用的是TCanvas的Handle。下面有兩個函數,它們的功能都是在一個填滿藍色的視窗上,畫上一個黃色框的圓,第一個函數是直接呼叫Windows GDI函數來繪製的,第二個函數則是使用C++ Builder提供的Canvas屬性。即使在不懂程式設計的人,也看得出來這兩個函數之中,第一個呼叫GDI函數的作法比較複雜難懂,相對地,使用Canvas屬性得作法就簡單明瞭,比前者容易多了。 void TMyWindows::Paint(TDC& PaintDC, bool erase, TRect& rect) { HPEN PenHandle , OlPenHandle; HBRUSH BrushHandle , OldBrushHandle; PenHandle = CreatePen(PS_SOLID , 1, RGB(0, 0, 255)); OldPenHandle = SelectObject(PaintDC , PenHandle); BrushHandle = CreatSolidBrush(RGB(255 , 255 ,0); OldBrushHandle = SelectObject(PaintDC , BrushHandle); Ellipse(10 , 20 , 50 , 50); SelectObject(OldBrushHandle); DeleteObject(BrushHandle); SelectObject(OldPenHandle); DeleteObject(PenHandle); } void __fastcall TForm1::FormPaint(TObject *Sender) { Cnavas->Pen->Color = clBlue; Canvas->Brush->Color =clYellow; Canvas->Ellipse(10 , 20 ,50, 50); } 你除了可以在畫布上由兩點單獨畫出一條直線之外,還可以透過Polyline方法來繪製一條連續的線,並進而產生出一個多邊的圖形,你只要宣告一個點座標結構組成的陣列,並且將想要繪製的各點座標值指定給陣列,傳入Polyline方法及可。下面的範例程式會在Form上繪製一個菱形圖形: void __fastcall TForm1::FormPaint(TObject *sender) { POINT p[5]; //POINT 是Windows宣告的點座標結構, 請查Win32 Help p[0].x=0; p[0].y=0; p[1].x=50; p[1].y=0; p[2].x=75; p[2].y=50; p[3].x=25; p[3].y=50; p[4].x=0; p[4].y=0; Canvas->Polyline(p,4); } 另外,TCanvas元件還提供一系列繪製固定圖形的功能,像是畫四方形的Rectangle 方法、畫橢圓或正圓形的Ellipse方法、畫圓角四方形的RoundRect方法、畫多邊形的Polygonz方法。下面的範例就是這些較高階繪製功能的程式: void ___fastcall TForm1::FormPaint(TObject *sender) { POINT p[3]; Canvas->Rectangle(0,0,ClientWidth/2,ClientHeight/2); Canvas->RoundRect(0,0,ClientWidth/2,ClientHeight/2,10,10); Canvas->Ellipse(0,0,ClientWidth/2,ClientHeight/2); p[0].x=0; p[0].y=0; p[1].x=0; p[1].y=ClientHeight; p[2].x=ClientWidth; p[2].y=ClientHeight; Canvas->Polygon(p,2); } 在TCanvas元件內具有四個重要的屬性,分別是畫線用的筆(Pen)、填圖用的筆刷(Brush)、寫字用的字型(Font)、用來顯示圖形的圖素陣列(Pixel Array)。實際上,當你利用個元件包含的Canvas屬性來畫圖時,你可以把每個Canvas想像成一張一張的畫布,每張畫布上的所有圖形都是由圖素(Pixel)組成的,每張畫布實際上就代表一個二維陣列,在陣列中的每個圖素都具有特定的顏色,你可以讀取或設定畫布陣列上的每個圖素。下面是圖素顏色的讀取與設定: Label1->Font->Color=Form1->Canvas->Pixels[5][5]; //讀取圖素顏 色 Form1->Canvas->Pixels[5][5]=clBlue; //設定圖素顏 色 一般在使用TCanvas時,很少會去直接存取圖素,除了在影像處理方面,而比較會常用一些繪製圖素的工具,像是畫線、畫圓、填圖等功能,在畫布上繪製直線可以使用LineTo方法。下列程式是在Form被繪製時,在Form上畫兩條交叉的對角線(當Form被繪製時,會先去執行OnPaint事件函數): void __fastcall TForm1::FormPaint(TObject *sender) { Canvas->MoveTo(0,0); Canvas->LineTo(ClientWidth,ClientHeight); Canvas->MoveTo(0,ClientHeight); Canvas->LineTo(ClientWidth,0); } 上面程式的MoveTo方法是把畫線的畫筆(Pen)移到原點鐘(0,0),畫筆屬性會關係到畫出來到線條粗細及型態。畫筆元件TPen具有四個屬性,分別是顏色(Color)、線寬(Width)、線條樣式(Style)及顯示模式(Mode)。除了畫筆之外,還有一種就是筆刷(Brush)的功能,你可以使用筆刷來填滿畫布上一塊封閉的區塊,筆刷元件TBrush也包括三個屬性,分別是Color、Style、Bitmap。Color屬性是填入的顏色,Style屬性設定填入圖案的樣式,Bitmap屬性則是填入圖形資料。 在繪圖過程中,你必須要經常追蹤滑鼠指標所在的位置,幾乎所有的視覺化元件都會提供OnMouseDown、OnMouseUp、OnMouseMove等三個事件函數,你可以依據這三個函數來讀取滑鼠座標或是判斷是否有按下滑鼠左鍵。 以下是本實驗程式的程式碼: //-------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" //-------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; //-------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //-------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { if(OpenDialog1->Execute()) Image1->Picture->LoadFromFile(OpenDialog1->FileName); } //-------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { for(x=0;x<313;x ) {for(y=8;y<281;y ) {if((Canvas->Pixels[x][y]%6)%6<50) Canvas->Pixels[x][y]=clRed;}} } //-------------------------------------------------------------------- Unit1.h 的程式碼 //-------------------------------------------------------------------- #ifndef Unit1H #define Unit1H //-------------------------------------------------------------------- #include #include #include #include #include #include //-------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TButton *Button1; TButton *Button2; TImage *Image1; TOpenDialog *OpenDialog1; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); private: int x,y; // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner); }; //-------------------------------------------------------------------- extern TForm1 *Form1; #endif
********************************************************************
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |